Dela via


Skapa en Windows PowerShell-containerprovider

I det här avsnittet beskrivs hur du skapar en Windows PowerShell-provider som kan arbeta med datalager i flera lager. För den här typen av datalager innehåller lagrets översta nivå rotobjekten och varje efterföljande nivå kallas för en nod med underordnade objekt. Genom att låta användaren arbeta med dessa underordnade noder kan en användare interagera hierarkiskt genom datalagret.

Leverantörer som kan arbeta med datalager på flera nivåer kallas Windows PowerShell-containerleverantörer. Tänk dock på att en Windows PowerShell-containerprovider endast kan användas när det finns en container (inga kapslade containrar) med objekt i den. Om det finns kapslade containrar måste du implementera en Windows PowerShell-navigeringsprovider. Mer information om hur du implementerar Windows PowerShell-navigeringsprovidern finns i Skapa en Windows PowerShell-navigeringsprovider.

Anmärkning

Du kan ladda ned C#-källfilen (AccessDBSampleProvider04.cs) för den här providern med hjälp av Microsoft Windows Software Development Kit för Windows Vista och .NET Framework 3.0 Runtime Components. Instruktioner för nedladdning finns i Så här installerar du Windows PowerShell och laddar ned Windows PowerShell SDK. De nedladdade källfilerna är tillgängliga i katalogen <PowerShell-exempel>. Mer information om andra Implementeringar av Windows PowerShell-providern finns i Designing Your Windows PowerShell Provider.

Windows PowerShell-containerprovidern som beskrivs här definierar databasen som sin enda container, med tabellerna och raderna i databasen definierade som objekt i containern.

Försiktighet

Tänk på att den här designen förutsätter en databas som har ett fält med namn-ID och att typen av fält är LongInteger.

Definiera en Windows PowerShell-containerproviderklass

En Windows PowerShell-containerprovider måste definiera en .NET-klass som härleds från basklassen System.Management.Automation.Provider.ContainerCmdletProvider. Här är klassdefinitionen för Windows PowerShell-containerprovidern som beskrivs i det här avsnittet.

[CmdletProvider("AccessDB", ProviderCapabilities.None)]
public class AccessDBProvider : ContainerCmdletProvider

Observera att attributet System.Management.Automation.Provider.CmdletProviderAttribute innehåller två parametrar i den här klassdefinitionen. Den första parametern anger ett användarvänligt namn för providern som används av Windows PowerShell. Den andra parametern anger de Windows PowerShell-specifika funktioner som providern exponerar för Windows PowerShell-körningen under kommandobearbetningen. För den här providern finns det inga Windows PowerShell-specifika funktioner som läggs till.

Definiera basfunktioner

Enligt beskrivningen i Designing Your Windows PowerShell Provider, härleds klassen System.Management.Automation.Provider.ContainerCmdletProvider från flera andra klasser som tillhandahåller olika providerfunktioner. En Windows PowerShell-containerprovider måste därför definiera alla funktioner som tillhandahålls av dessa klasser.

Information om hur du implementerar funktioner för att lägga till sessionsspecifik initieringsinformation och för att frigöra resurser som används av providern finns i Skapa en grundläggande Windows PowerShell-provider. De flesta leverantörer (inklusive providern som beskrivs här) kan dock använda standardimplementeringen av den här funktionen som tillhandahålls av Windows PowerShell.

För att få åtkomst till datalagret måste providern implementera metoderna i basklassen System.Management.Automation.Provider.DriveCmdletProvider. Mer information om hur du implementerar dessa metoder finns i Skapa en Windows PowerShell-enhetsprovider.

Om du vill ändra objekten i ett datalager, till exempel hämta, ange och rensa objekt, måste providern implementera de metoder som tillhandahålls av System.Management.Automation.Provider.ItemCmdletProvider basklass. Mer information om hur du implementerar dessa metoder finns i Skapa en Windows PowerShell-objektprovider.

Hämtar underordnade objekt

För att hämta ett underordnat objekt måste Windows PowerShell-containerprovidern åsidosätta System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* metod för att stödja anrop från cmdleten Get-ChildItem. Den här metoden hämtar underordnade objekt från datalagret och skriver dem till pipelinen som objekt. Om recurse parametern för cmdleten anges hämtar metoden alla underordnade oavsett vilken nivå de är på. Om parametern recurse inte anges hämtar metoden endast en enda nivå av underordnade.

Här är implementeringen av System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* metod för den här providern. Observera att den här metoden hämtar underordnade objekt i alla databastabeller när sökvägen anger Access-databasen och hämtar de underordnade objekten från raderna i tabellen om sökvägen anger en datatabell.

protected override void GetChildItems(string path, bool recurse)
{
    // If path represented is a drive then the children in the path are 
    // tables. Hence all tables in the drive represented will have to be
    // returned
    if (PathIsDrive(path))
    {
        foreach (DatabaseTableInfo table in GetTables())
        {
            WriteItemObject(table, path, true);

            // if the specified item exists and recurse has been set then 
            // all child items within it have to be obtained as well
            if (ItemExists(path) && recurse)
            {
                GetChildItems(path + pathSeparator + table.Name, recurse);
            }
        } // foreach (DatabaseTableInfo...
    } // if (PathIsDrive...
    else
    {
        // Get the table name, row number and type of path from the
        // path specified
        string tableName;
        int rowNumber;

        PathType type = GetNamesFromPath(path, out tableName, out rowNumber);

        if (type == PathType.Table)
        {
            // Obtain all the rows within the table
            foreach (DatabaseRowInfo row in GetRows(tableName))
            {
                WriteItemObject(row, path + pathSeparator + row.RowNumber,
                        false);
            } // foreach (DatabaseRowInfo...
        }
        else if (type == PathType.Row)
        {
            // In this case the user has directly specified a row, hence
            // just give that particular row
            DatabaseRowInfo row = GetRow(tableName, rowNumber);
            WriteItemObject(row, path + pathSeparator + row.RowNumber,
                        false);
        }
        else
        {
            // In this case, the path specified is not valid
            ThrowTerminatingInvalidPathException(path);
        }
    } // else
} // GetChildItems

Saker att komma ihåg om att implementera GetChildItems

Följande villkor kan gälla för implementeringen av System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems*:

Koppla dynamiska parametrar till cmdleten Get-ChildItem

Ibland kräver den Get-ChildItem cmdlet som anropar System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* ytterligare parametrar som anges dynamiskt vid körning. För att tillhandahålla dessa dynamiska parametrar måste Windows PowerShell-containerprovidern implementera metoden System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItemsDynamicParameters*. Den här metoden hämtar dynamiska parametrar för objektet på den angivna sökvägen och returnerar ett objekt som har egenskaper och fält med parsningsattribut som liknar en cmdlet-klass eller en System.Management.Automation.RuntimeDefinedParameterDictionary-objekt. Windows PowerShell-körningen använder det returnerade objektet för att lägga till parametrarna i cmdleten Get-ChildItem.

Den här Windows PowerShell-containerprovidern implementerar inte den här metoden. Följande kod är dock standardimplementeringen av den här metoden.

Hämtar underordnade objektnamn

Om du vill hämta namnen på underordnade objekt måste Windows PowerShell-containerprovidern åsidosätta System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNames*-metoden för att stödja anrop från Get-ChildItem cmdlet när parametern Name anges. Den här metoden hämtar namnen på de underordnade objekten för den angivna sökvägen eller underordnade objektnamn för alla containrar om parametern returnAllContainers för cmdleten har angetts. Ett underordnat namn är lövdelen av en sökväg. Till exempel är det underordnade namnet på sökvägen C:\windows\system32\abc.dll "abc.dll". Det underordnade namnet på katalogen C:\windows\system32 är "system32".

Här är implementeringen av System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNames* metod för den här providern. Observera att metoden hämtar tabellnamn om den angivna sökvägen anger Access-databasen (enhet) och radnummer om sökvägen anger en tabell.

protected override void GetChildNames(string path,
                              ReturnContainers returnContainers)
{
    // If the path represented is a drive, then the child items are
    // tables. get the names of all the tables in the drive.
    if (PathIsDrive(path))
    {
        foreach (DatabaseTableInfo table in GetTables())
        {
            WriteItemObject(table.Name, path, true);
        } // foreach (DatabaseTableInfo...
    } // if (PathIsDrive...
    else
    {
        // Get type, table name and row number from path specified
        string tableName;
        int rowNumber;

        PathType type = GetNamesFromPath(path, out tableName, out rowNumber);

        if (type == PathType.Table)
        {
            // Get all the rows in the table and then write out the 
            // row numbers.
            foreach (DatabaseRowInfo row in GetRows(tableName))
            {
                WriteItemObject(row.RowNumber, path, false);
            } // foreach (DatabaseRowInfo...
        }
        else if (type == PathType.Row)
        {
            // In this case the user has directly specified a row, hence
            // just give that particular row
            DatabaseRowInfo row = GetRow(tableName, rowNumber);

            WriteItemObject(row.RowNumber, path, false);
        }
        else
        {
            ThrowTerminatingInvalidPathException(path);
        }
    } // else
} // GetChildNames

Saker att komma ihåg om att implementera GetChildNames

Följande villkor kan gälla för implementeringen av System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems*:

Koppla dynamiska parametrar till cmdleten Get-ChildItem (namn)

Ibland kräver Get-ChildItem-cmdleten (med parametern Name) ytterligare parametrar som anges dynamiskt vid körning. För att tillhandahålla dessa dynamiska parametrar måste Windows PowerShell-containerprovidern implementera metoden System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNamesDynamicParameters*. Den här metoden hämtar de dynamiska parametrarna för objektet på den angivna sökvägen och returnerar ett objekt som har egenskaper och fält med parsningsattribut som liknar en cmdlet-klass eller en System.Management.Automation.RuntimeDefinedParameterDictionary-objekt. Windows PowerShell-körningen använder det returnerade objektet för att lägga till parametrarna i cmdleten Get-ChildItem.

Den här providern implementerar inte den här metoden. Följande kod är dock standardimplementeringen av den här metoden.

Byta namn på objekt

Om du vill byta namn på ett objekt måste en Windows PowerShell-containerprovider åsidosätta System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem*-metoden för att stödja anrop från cmdleten Rename-Item. Den här metoden ändrar namnet på objektet på den angivna sökvägen till det nya angivna namnet. Det nya namnet måste alltid vara relativt det överordnade objektet (containern).

Den här providern åsidosätter inte metoden System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem*. Följande är dock standardimplementeringen.

Saker att komma ihåg om att implementera RenameItem

Följande villkor kan gälla för implementeringen av System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem*:

Koppla dynamiska parametrar till cmdleten Rename-Item

Ibland kräver Rename-Item-cmdleten ytterligare parametrar som anges dynamiskt vid körning. För att tillhandahålla dessa dynamiska parametrar måste Windows PowerShell-containerprovidern implementera System.Management.Automation.Provider.ContainerCmdletProvider.RenameItemDynamicParameters*-metoden. Den här metoden hämtar parametrarna för objektet på den angivna sökvägen och returnerar ett objekt som har egenskaper och fält med parsningsattribut som liknar en cmdlet-klass eller en System.Management.Automation.RuntimeDefinedParameterDictionary-objekt. Windows PowerShell-körningen använder det returnerade objektet för att lägga till parametrarna i cmdleten Rename-Item.

Den här containerprovidern implementerar inte den här metoden. Följande kod är dock standardimplementeringen av den här metoden.

Skapa nya objekt

Om du vill skapa nya objekt måste en containerprovider implementera metoden System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* för att stödja anrop från cmdleten New-Item. Den här metoden skapar ett dataobjekt som finns på den angivna sökvägen. Parametern type för cmdleten innehåller den providerdefinierade typen för det nya objektet. FileSystem-providern använder till exempel en type-parameter med värdet "file" eller "directory". Parametern newItemValue för cmdleten anger ett providerspecifikt värde för det nya objektet.

Här är implementeringen av System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* metod för den här providern.

protected override void NewItem( string path, string type, object newItemValue )
{
    // Create the new item here after
    // performing necessary validations
    //
    // WriteItemObject(newItemValue, path, false);

    // Example
    //
    // if (ShouldProcess(path, "new item"))
    // {
    //      // Create a new item and then call WriteObject
    //      WriteObject(newItemValue, path, false);
    // }

} // NewItem
{
    case 1:
        {
            string name = pathChunks[0];

            if (TableNameIsValid(name))
            {
                tableName = name;
                retVal = PathType.Table;
            }
        }
        break;

    case 2:
        {
            string name = pathChunks[0];

Saker att komma ihåg när du implementerar NewItem

Följande villkor kan gälla för implementeringen av System.Management.Automation.Provider.ContainerCmdletProvider.NewItem*:

Koppla dynamiska parametrar till cmdleten New-Item

Ibland kräver New-Item-cmdleten ytterligare parametrar som anges dynamiskt vid körning. För att tillhandahålla dessa dynamiska parametrar måste containerprovidern implementera metoden System.Management.Automation.Provider.ContainerCmdletProvider.NewItemDynamicParameters*. Den här metoden hämtar parametrarna för objektet på den angivna sökvägen och returnerar ett objekt som har egenskaper och fält med parsningsattribut som liknar en cmdlet-klass eller en System.Management.Automation.RuntimeDefinedParameterDictionary-objekt. Windows PowerShell-körningen använder det returnerade objektet för att lägga till parametrarna i cmdleten New-Item.

Den här providern implementerar inte den här metoden. Följande kod är dock standardimplementeringen av den här metoden.

Ta bort objekt

Om du vill ta bort objekt måste Windows PowerShell-providern åsidosätta metoden System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItem* för att stödja anrop från cmdleten Remove-Item. Den här metoden tar bort ett objekt från datalagret på den angivna sökvägen. Om recurse-parametern för cmdleten Remove-Item är inställd på truetar metoden bort alla underordnade objekt oavsett nivå. Om parametern är inställd på falsetar metoden bara bort ett enskilt objekt på den angivna sökvägen.

Den här providern stöder inte borttagning av objekt. Följande kod är dock standardimplementeringen av System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItem*.

Saker att komma ihåg när du implementerar RemoveItem

Följande villkor kan gälla för implementeringen av System.Management.Automation.Provider.ContainerCmdletProvider.NewItem*:

Koppla dynamiska parametrar till cmdleten Remove-Item

Ibland kräver Remove-Item-cmdleten ytterligare parametrar som anges dynamiskt vid körning. För att tillhandahålla dessa dynamiska parametrar måste containerprovidern implementera metoden System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItemDynamicParameters* för att hantera dessa parametrar. Den här metoden hämtar de dynamiska parametrarna för objektet på den angivna sökvägen och returnerar ett objekt som har egenskaper och fält med parsningsattribut som liknar en cmdlet-klass eller en System.Management.Automation.RuntimeDefinedParameterDictionary-objekt. Windows PowerShell-körningen använder det returnerade objektet för att lägga till parametrarna i cmdleten Remove-Item.

Den här containerprovidern implementerar inte den här metoden. Följande kod är dock standardimplementeringen av System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItemDynamicParameters*.

Fråga efter underordnade objekt

För att kontrollera om underordnade objekt finns på den angivna sökvägen måste Windows PowerShell-containerprovidern åsidosätta System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems*-metoden. Den här metoden returnerar true om objektet har underordnade objekt och false annat. För en null- eller tom sökväg anser metoden att alla objekt i datalagret är underordnade och returnerar true.

Här är åsidosättningen för metoden System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems*. Om det finns fler än två sökvägsdelar som skapats av ChunkPath-hjälpmetoden returnerar metoden falseeftersom endast en databascontainer och en tabellcontainer definieras. Mer information om den här hjälpmetoden finns i ChunkPath-metoden beskrivs i Skapa en Windows PowerShell-objektprovider.

protected override bool HasChildItems( string path )
{
    return false;
} // HasChildItems
        ErrorCategory.InvalidOperation, tableName));
}

return results;

Saker att komma ihåg om att implementera HasChildItems

Följande villkor kan gälla för implementeringen av System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems*:

Kopiera objekt

Om du vill kopiera objekt måste containerprovidern implementera metoden System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem för att stödja anrop från cmdleten Copy-Item. Den här metoden kopierar ett dataobjekt från den plats som anges av path-parametern för cmdleten till den plats som anges av parametern copyPath. Om parametern recurse anges kopierar metoden alla undercontainrar. Om parametern inte anges kopierar metoden endast en enskild objektnivå.

Den här providern implementerar inte den här metoden. Följande kod är dock standardimplementeringen av System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem.

Saker att komma ihåg om att implementera CopyItem

Följande villkor kan gälla för implementeringen av System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem:

Koppla dynamiska parametrar till cmdleten Copy-Item

Ibland kräver Copy-Item-cmdleten ytterligare parametrar som anges dynamiskt vid körning. För att tillhandahålla dessa dynamiska parametrar måste Windows PowerShell-containerprovidern implementera System.Management.Automation.Provider.ContainerCmdletProvider.CopyItemDynamicParameters*-metoden för att hantera dessa parametrar. Den här metoden hämtar parametrarna för objektet på den angivna sökvägen och returnerar ett objekt som har egenskaper och fält med parsningsattribut som liknar en cmdlet-klass eller en System.Management.Automation.RuntimeDefinedParameterDictionary-objekt. Windows PowerShell-körningen använder det returnerade objektet för att lägga till parametrarna i cmdleten Copy-Item.

Den här providern implementerar inte den här metoden. Följande kod är dock standardimplementeringen av System.Management.Automation.Provider.ContainerCmdletProvider.CopyItemDynamicParameters*.

Kodexempel

Fullständig exempelkod finns i AccessDbProviderSample04 Code Sample.

Skapa Windows PowerShell-providern

Se Så här registrerar du cmdletar, leverantörer och värdprogram.

Testa Windows PowerShell-providern

När din Windows PowerShell-provider har registrerats med Windows PowerShell kan du testa den genom att köra de cmdletar som stöds på kommandoraden. Tänk på att följande exempelutdata använder en fiktiv Access-databas.

  1. Kör cmdleten Get-ChildItem för att hämta listan över underordnade objekt från en kundtabell i Access-databasen.

    Get-ChildItem mydb:customers
    

    Följande utdata visas.

    PSPath        : AccessDB::customers
    PSDrive       : mydb
    PSProvider    : System.Management.Automation.ProviderInfo
    PSIsContainer : True
    Data          : System.Data.DataRow
    Name          : Customers
    RowCount      : 91
    Columns       :
    
  2. Kör cmdleten Get-ChildItem igen för att hämta data i en tabell.

    (Get-ChildItem mydb:customers).Data
    

    Följande utdata visas.

    TABLE_CAT   : C:\PS\northwind
    TABLE_SCHEM :
    TABLE_NAME  : Customers
    TABLE_TYPE  : TABLE
    REMARKS     :
    
  3. Använd nu cmdleten Get-Item för att hämta objekten på rad 0 i datatabellen.

    Get-Item mydb:\customers\0
    

    Följande utdata visas.

    PSPath        : AccessDB::customers\0
    PSDrive       : mydb
    PSProvider    : System.Management.Automation.ProviderInfo
    PSIsContainer : False
    Data          : System.Data.DataRow
    RowNumber     : 0
    
  4. Återanvänd Get-Item för att hämta data för objekten på rad 0.

    (Get-Item mydb:\customers\0).Data
    

    Följande utdata visas.

    CustomerID   : 1234
    CompanyName  : Fabrikam
    ContactName  : Eric Gruber
    ContactTitle : President
    Address      : 4567 Main Street
    City         : Buffalo
    Region       : NY
    PostalCode   : 98052
    Country      : USA
    Phone        : (425) 555-0100
    Fax          : (425) 555-0101
    
  5. Använd nu cmdleten New-Item för att lägga till en rad i en befintlig tabell. Parametern Path anger den fullständiga sökvägen till raden och måste ange ett radnummer som är större än det befintliga antalet rader i tabellen. Parametern Type anger Row för att ange den typ av objekt som ska läggas till. Slutligen anger parametern Value en kommaavgränsad lista med kolumnvärden för raden.

    New-Item -Path mydb:\Customers\3 -ItemType "Row" -Value "3,CustomerFirstName,CustomerLastName,CustomerEmailAddress,CustomerTitle,CustomerCompany,CustomerPhone, CustomerAddress,CustomerCity,CustomerState,CustomerZip,CustomerCountry"
    
  6. Kontrollera att den nya objektåtgärden är korrekt enligt följande.

    PS mydb:\> cd Customers
    PS mydb:\Customers> (Get-Item 3).Data
    

    Följande utdata visas.

    ID        : 3
    FirstName : Eric
    LastName  : Gruber
    Email     : ericgruber@fabrikam.com
    Title     : President
    Company   : Fabrikam
    WorkPhone : (425) 555-0100
    Address   : 4567 Main Street
    City      : Buffalo
    State     : NY
    Zip       : 98052
    Country   : USA
    

Se även

Skapa Windows PowerShell-providers

utforma din Windows PowerShell-provider

Implementera en Windows PowerShell-provider för objekt

Implementera en Windows PowerShell-provider för navigering

Registrera cmdletar, leverantörer och värdprogram

Windows PowerShell SDK

Windows PowerShell-programmerarens guide