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

Skriva en containerprovider

Skriva en navigeringsprovider

Översikt över Windows PowerShell-providers