Skriva en objektprovider
I det här avsnittet beskrivs hur du implementerar metoder för en Windows PowerShell provider som kommer åt och ändrar objekt i datalagret. För att kunna komma åt objekt måste en provider härledas från klassen System.Management.Automation.Provider.Itemcmdletprovider.
Providern i exemplen i det här avsnittet använder en Access-databas som datalager. Det finns flera hjälpmetoder och klasser som används för att interagera med databasen. Det fullständiga exemplet som innehåller hjälpmetoderna finns i AccessDBProviderSample03
Mer information om Windows PowerShell finns i översikten Windows PowerShell provider.
Implementera objektmetoder
Klassen System.Management.Automation.Provider.Itemcmdletprovider visar flera metoder som kan användas för att komma åt och ändra objekten i ett datalager. En fullständig lista över dessa metoder finns i ItemCmdletProvider Methods. I det här exemplet implementerar vi fyra av dessa metoder. System.Management.Automation.Provider.Itemcmdletprovider.Getitem* hämtar ett objekt på en angiven sökväg. System.Management.Automation.Provider.Itemcmdletprovider.Setitem* anger värdet för det angivna objektet. System.Management.Automation.Provider.Itemcmdletprovider.Itemexists* kontrollerar om ett objekt finns på den angivna sökvägen. System.Management.Automation.Provider.Itemcmdletprovider.Isvalidpath* kontrollerar en sökväg för att se om den mappar till en plats i datalagret.
Anteckning
Det här avsnittet bygger på informationen i snabbstarten Windows PowerShell provider. Det här avsnittet går inte in på grunderna i hur du ställer in ett providerprojekt eller hur du implementerar de metoder som ärvts från klassen System.Management.Automation.Provider.Drivecmdletprovider som skapar och tar bort enheter.
Deklarera providerklassen
Deklarera providern så att den härleds från klassen System.Management.Automation.Provider.Itemcmdletprovider och förser den med klassen System.Management.Automation.Provider.Cmdletproviderattribute.
[CmdletProvider("AccessDB", ProviderCapabilities.None)]
public class AccessDBProvider : ItemCmdletProvider
{
}
Implementera GetItem
System.Management.Automation.Provider.Itemcmdletprovider.Getitem* anropas av PowerShell-motorn när en användare anropar cmdleten Microsoft.PowerShell.Commands.GetItemCommand på din provider. Metoden returnerar objektet på den angivna sökvägen. I exemplet med Access-databasen kontrollerar metoden om objektet är själva enheten, en tabell i databasen eller en rad i databasen. Metoden skickar objektet till PowerShell-motorn genom att anropa metoden System.Management.Automation.Provider.Cmdletprovider.Writeitemobject*.
protected override void GetItem(string path)
{
// check if the path represented is a drive
if (PathIsDrive(path))
{
WriteItemObject(this.PSDriveInfo, path, true);
return;
}// if (PathIsDrive...
// Get table name and row information from the path and do
// necessary actions
string tableName;
int rowNumber;
PathType type = GetNamesFromPath(path, out tableName, out rowNumber);
if (type == PathType.Table)
{
DatabaseTableInfo table = GetTable(tableName);
WriteItemObject(table, path, true);
}
else if (type == PathType.Row)
{
DatabaseRowInfo row = GetRow(tableName, rowNumber);
WriteItemObject(row, path, false);
}
else
{
ThrowTerminatingInvalidPathException(path);
}
}
Implementera SetItem
Metoden System.Management.Automation.Provider.Itemcmdletprovider.Setitem* anropas av PowerShell-motorn när en användare anropar cmdleten Microsoft.PowerShell.Commands.SetItemCommand. Den anger värdet för objektet på den angivna sökvägen.
I Access-databasexe exemplet är det klokt att ange värdet för ett objekt endast om objektet är en rad, så metoden kastar NotSupportedException när objektet inte är en rad.
protected override void SetItem(string path, object values)
{
// Get type, table name and row number from the path specified
string tableName;
int rowNumber;
PathType type = GetNamesFromPath(path, out tableName, out rowNumber);
if (type != PathType.Row)
{
WriteError(new ErrorRecord(new NotSupportedException(
"SetNotSupported"), "",
ErrorCategory.InvalidOperation, path));
return;
}
// Get in-memory representation of table
OdbcDataAdapter da = GetAdapterForTable(tableName);
if (da == null)
{
return;
}
DataSet ds = GetDataSetForTable(da, tableName);
DataTable table = GetDataTable(ds, tableName);
if (rowNumber >= table.Rows.Count)
{
// The specified row number has to be available. If not
// NewItem has to be used to add a new row
throw new ArgumentException("Row specified is not available");
} // if (rowNum...
string[] colValues = (values as string).Split(',');
// set the specified row
DataRow row = table.Rows[rowNumber];
for (int i = 0; i < colValues.Length; i++)
{
row[i] = colValues[i];
}
// Update the table
if (ShouldProcess(path, "SetItem"))
{
da.Update(ds, tableName);
}
}
Implementera ItemExists
Metoden System.Management.Automation.Provider.Itemcmdletprovider.Itemexists* anropas av PowerShell-motorn när en användare anropar cmdleten Microsoft.PowerShell.Commands.TestPathCommand. Metoden avgör om det finns ett objekt på den angivna sökvägen. Om objektet finns skickar metoden tillbaka det till PowerShell-motorn genom att anropa System.Management.Automation.Provider.Cmdletprovider.Writeitemobject*.
protected override bool ItemExists(string path)
{
// check if the path represented is a drive
if (PathIsDrive(path))
{
return true;
}
// Obtain type, table name and row number from path
string tableName;
int rowNumber;
PathType type = GetNamesFromPath(path, out tableName, out rowNumber);
DatabaseTableInfo table = GetTable(tableName);
if (type == PathType.Table)
{
// if specified path represents a table then DatabaseTableInfo
// object for the same should exist
if (table != null)
{
return true;
}
}
else if (type == PathType.Row)
{
// if specified path represents a row then DatabaseTableInfo should
// exist for the table and then specified row number must be within
// the maximum row count in the table
if (table != null && rowNumber < table.RowCount)
{
return true;
}
}
return false;
}
Implementera IsValidPath
Metoden System.Management.Automation.Provider.Itemcmdletprovider.Isvalidpath* kontrollerar om den angivna sökvägen är syntaktiskt giltig för den aktuella providern. Den kontrollerar inte om ett objekt finns på sökvägen.
protected override bool IsValidPath(string path)
{
bool result = true;
// check if the path is null or empty
if (String.IsNullOrEmpty(path))
{
result = false;
}
// convert all separators in the path to a uniform one
path = NormalizePath(path);
// split the path into individual chunks
string[] pathChunks = path.Split(pathSeparator.ToCharArray());
foreach (string pathChunk in pathChunks)
{
if (pathChunk.Length == 0)
{
result = false;
}
}
return result;
}
Nästa steg
En typisk verklig provider kan stödja objekt som innehåller andra objekt och flytta objekt från en sökväg till en annan på enheten. Ett exempel på en provider som stöder containrar finns i Skriva en containerprovider. Ett exempel på en provider som stöder flytt av objekt finns i Skriva en navigeringsprovider.
Se även
Feedback
Skicka och visa feedback för