Partilhar via


Criação de um Fornecedor de Contentores Windows PowerShell

Este tópico descreve como criar um fornecedor Windows PowerShell que possa funcionar em armazenamentos de dados multicamada. Para este tipo de armazenamento de dados, o nível superior do armazenamento contém os itens raiz e cada nível subsequente é referido como nó de itens filhos. Ao permitir que o utilizador trabalhe nestes nós filhos, o utilizador pode interagir hierarquicamente através do armazenamento de dados.

Os fornecedores que conseguem trabalhar em armazenamentos de dados multinível são chamados fornecedores de contentores Windows PowerShell. No entanto, esteja ciente de que um fornecedor de contentores Windows PowerShell só pode ser usado quando existe um contentor (sem containers aninhados) com itens no seu interior. Se existirem containers aninhados, então deve implementar um fornecedor de navegação Windows PowerShell. Para mais informações sobre a implementação do fornecedor de navegação Windows PowerShell, consulte Criação de um Fornecedor de Navegação Windows PowerShell.

Observação

Pode descarregar o ficheiro-fonte C# (AccessDBSampleProvider04.cs) deste fornecedor utilizando o Microsoft Windows Software Development Kit para Windows Vista e os Componentes de Runtime do .NET Framework 3.0. Para instruções de download, consulte Como Instalar o Windows PowerShell e Descarregar o Windows PowerShell SDK. Os ficheiros fonte descarregados estão disponíveis no <diretório PowerShell Samples> . Para mais informações sobre outras implementações de fornecedores Windows PowerShell, consulte Designing Your Windows PowerShell Provider.

O fornecedor de contentores Windows PowerShell descrito aqui define a base de dados como o seu único contentor, com as tabelas e linhas da base de dados definidas como itens do contentor.

Atenção

Tenha em atenção que este design assume uma base de dados que tem um campo com o nome ID, e que o tipo do campo é LongInteger.

Definição de uma Classe de Fornecedor de Contentores Windows PowerShell

Um fornecedor de contentores Windows PowerShell deve definir uma classe .NET que derive da classe base System.Management.Automation.Provider.ContainerCmdletProvider . Aqui está a definição de classe para o fornecedor de contentores Windows PowerShell descrito nesta secção.

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

Note que, nesta definição de classe, o atributo System.Management.Automation.Provider.CmdletProviderAddition inclui dois parâmetros. O primeiro parâmetro especifica um nome amigável para o fornecedor utilizado pelo Windows PowerShell. O segundo parâmetro especifica as capacidades específicas do Windows PowerShell que o fornecedor expõe ao tempo de execução do Windows PowerShell durante o processamento de comandos. Para este fornecedor, não são adicionadas capacidades específicas do PowerShell do Windows.

Definição da Funcionalidade Base

Como descrito em Designing Your Windows PowerShell Provider, a classe System.Management.Automation.Provider.ContainerCmdletProvider deriva de várias outras classes que forneciam funcionalidades diferentes de fornecedores. Um fornecedor de contentores Windows PowerShell, portanto, precisa de definir toda a funcionalidade fornecida por essas classes.

Para implementar funcionalidades para adicionar informação de inicialização específica da sessão e para libertar recursos usados pelo fornecedor, veja Criar um Fornecedor Básico de PowerShell para Windows. No entanto, a maioria dos fornecedores (incluindo o fornecedor descrito aqui) pode usar a implementação padrão desta funcionalidade fornecida pelo Windows PowerShell.

Para aceder ao armazenamento de dados, o fornecedor deve implementar os métodos da classe base System.Management.Automation.Provider.DriveCmdletProvider . Para mais informações sobre como implementar estes métodos, consulte Criar um Fornecedor de Unidades PowerShell para Windows.

Para manipular os itens de um armazenamento de dados, como obtenção, definição e compensação de itens, o fornecedor deve implementar os métodos fornecidos pela classe base System.Management.Automation.Provider.ItemCmdletProvider . Para mais informações sobre a implementação destes métodos, consulte Criação de um Fornecedor de Itens para Windows PowerShell.

Recuperação de Itens Crianças

Para recuperar um item filho, o fornecedor do contentor Windows PowerShell deve sobrescrever o método System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* para suportar chamadas do Get-ChildItem cmdlet. Este método recupera itens filhos do armazenamento de dados e escreve-os no pipeline como objetos. Se o recurse parâmetro do cmdlet for especificado, o método recupera todos os filhos, independentemente do nível em que se encontram. Se o recurse parâmetro não for especificado, o método recupera apenas um único nível de filhos.

Aqui está a implementação do método System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* para este fornecedor. Note que este método recupera os itens filhos em todas as tabelas da base de dados quando o caminho indica a base de dados Access, e recupera os itens filhos das linhas dessa tabela se o caminho indicar uma tabela de dados.

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

Coisas a Lembrar Sobre a Implementação do GetChildItems

As seguintes condições podem aplicar-se à sua implementação de System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems*:

Anexação de Parâmetros Dinâmicos ao Cmdlet Get-ChildItem

Por vezes, o Get-ChildItem cmdlet que chama System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems* requer parâmetros adicionais que são especificados dinamicamente em tempo de execução. Para fornecer estes parâmetros dinâmicos, o fornecedor de contentores Windows PowerShell deve implementar o método System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItemsDynamicParameters* . Este método recupera parâmetros dinâmicos para o item no caminho indicado e devolve um objeto com propriedades e campos com atributos de análise semelhantes a uma classe cmdlet ou a um objeto System.Management.Automation.RuntimeDefinedParameterDictionary . O runtime do Windows PowerShell usa o objeto devolvido para adicionar os parâmetros ao Get-ChildItem cmdlet.

Este fornecedor de contentores Windows PowerShell não implementa este método. No entanto, o código seguinte é a implementação padrão deste método.

Recuperação de Nomes de Itens Filhos

Para recuperar os nomes dos itens filhos, o fornecedor do contentor PowerShell do Windows deve sobrescrever o método System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNames* para suportar chamadas do Get-ChildItem cmdlet quando o seu Name parâmetro é especificado. Este método recupera os nomes dos itens filhos para o caminho especificado ou os nomes dos itens filhos para todos os contentores, se o returnAllContainers parâmetro do cmdlet for especificado. Um nome de criança é a parte folhosa de um caminho. Por exemplo, o nome filho do caminho C:\windows\system32\abc.dll é "abc.dll". O nome filho do diretório C:\windows\system32 é "system32".

Aqui está a implementação do método System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNames* para este fornecedor. Note que o método recupera nomes de tabelas se o caminho especificado indicar a base de dados de acesso (disco) e números de linha se o caminho indicar uma tabela.

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

Coisas a Lembrar Sobre a Implementação do GetChildNames

As seguintes condições podem aplicar-se à sua implementação de System.Management.Automation.Provider.ContainerCmdletProvider.GetChildItems*:

Anexar parâmetros dinâmicos ao cmdlet de Get-ChildItem (nome)

Por vezes, o Get-ChildItem cmdlet (com o Name parâmetro) requer parâmetros adicionais que são especificados dinamicamente em tempo de execução. Para fornecer estes parâmetros dinâmicos, o fornecedor de contentores Windows PowerShell deve implementar o método System.Management.Automation.Provider.ContainerCmdletProvider.GetChildNamesDynamicParameters* . Este método recupera os parâmetros dinâmicos do item no caminho indicado e devolve um objeto que possui propriedades e campos com atributos de análise semelhantes a uma classe cmdlet ou a um objeto System.Management.Automation.RuntimeDefinedParameterDictionary . O runtime do Windows PowerShell usa o objeto devolvido para adicionar os parâmetros ao Get-ChildItem cmdlet.

Este fornecedor não implementa este método. No entanto, o código seguinte é a implementação padrão deste método.

Renomeação dos Itens

Para renomear um item, um fornecedor de contentores Windows PowerShell deve sobrescrever o método System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem* para suportar chamadas do Rename-Item cmdlet. Este método altera o nome do item no caminho especificado para o novo nome fornecido. O novo nome deve ser sempre relativo ao item pai (contentor).

Este fornecedor não sobrepõe o método System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem* . No entanto, a seguinte é a implementação padrão.

Coisas a Lembrar Sobre a Implementação do RenameItem

As seguintes condições podem aplicar-se à sua implementação de System.Management.Automation.Provider.ContainerCmdletProvider.RenameItem*:

Anexação de Parâmetros Dinâmicos ao Cmdlet Rename-Item

Por vezes, o Rename-Item cmdlet requer parâmetros adicionais que são especificados dinamicamente em tempo de execução. Para fornecer estes parâmetros dinâmicos, o fornecedor de contentores Windows PowerShell deve implementar o método System.Management.Automation.Provider.ContainerCmdletProvider.RenameItemDynamicParameters* . Este método recupera os parâmetros do item no caminho indicado e devolve um objeto com propriedades e campos com atributos de análise semelhantes a uma classe cmdlet ou a um objeto System.Management.Automation.RuntimeDefinedParameterDictionary . O runtime do Windows PowerShell usa o objeto devolvido para adicionar os parâmetros ao Rename-Item cmdlet.

Este fornecedor de contentores não implementa este método. No entanto, o código seguinte é a implementação padrão deste método.

Criação de Novos Itens

Para criar novos itens, um fornecedor de contentores deve implementar o método System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* para suportar chamadas do New-Item cmdlet. Este método cria um elemento de dados localizado no caminho especificado. O type parâmetro do cmdlet contém o tipo definido pelo fornecedor para o novo item. Por exemplo, o fornecedor do Sistema de Ficheiros usa um type parâmetro com o valor de "ficheiro" ou "diretório". O newItemValue parâmetro do cmdlet especifica um valor específico do fornecedor para o novo item.

Aqui está a implementação do método System.Management.Automation.Provider.ContainerCmdletProvider.NewItem* para este fornecedor.

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];

Coisas a Lembrar Sobre a Implementação do NewItem

As seguintes condições podem aplicar-se à sua implementação de System.Management.Automation.Provider.ContainerCmdletProvider.NewItem*:

Anexação de Parâmetros Dinâmicos ao Cmdlet New-Item

Por vezes, o New-Item cmdlet requer parâmetros adicionais que são especificados dinamicamente em tempo de execução. Para fornecer estes parâmetros dinâmicos, o fornecedor do contentor deve implementar o método System.Management.Automation.Provider.ContainerCmdletProvider.NewItemDynamicParameters* . Este método recupera os parâmetros do item no caminho indicado e devolve um objeto com propriedades e campos com atributos de análise semelhantes a uma classe cmdlet ou a um objeto System.Management.Automation.RuntimeDefinedParameterDictionary . O runtime do Windows PowerShell usa o objeto devolvido para adicionar os parâmetros ao New-Item cmdlet.

Este fornecedor não implementa este método. No entanto, o código seguinte é a implementação padrão deste método.

Remoção de Itens

Para remover elementos, o fornecedor PowerShell do Windows deve sobrescrever o método System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItem* para suportar chamadas do Remove-Item cmdlet. Este método elimina um item do armazenamento de dados no caminho especificado. Se o recurse parâmetro do Remove-Item cmdlet for definido para true, o método remove todos os itens filhos, independentemente do seu nível. Se o parâmetro for definido para false, o método remove apenas um item no caminho especificado.

Este fornecedor não suporta a remoção de artigos. No entanto, o código seguinte é a implementação padrão do System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItem*.

Coisas a Lembrar Sobre a Implementação do RemoveItem

As seguintes condições podem aplicar-se à sua implementação de System.Management.Automation.Provider.ContainerCmdletProvider.NewItem*:

Anexação de Parâmetros Dinâmicos ao Cmdlet Remove-Item

Por vezes, o Remove-Item cmdlet requer parâmetros adicionais que são especificados dinamicamente em tempo de execução. Para fornecer estes parâmetros dinâmicos, o fornecedor do contentor deve implementar o método System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItemDynamicParameters* para lidar com estes parâmetros. Este método recupera os parâmetros dinâmicos do item no caminho indicado e devolve um objeto que possui propriedades e campos com atributos de análise semelhantes a uma classe cmdlet ou a um objeto System.Management.Automation.RuntimeDefinedParameterDictionary . O runtime do Windows PowerShell usa o objeto devolvido para adicionar os parâmetros ao Remove-Item cmdlet.

Este fornecedor de contentores não implementa este método. No entanto, o código seguinte é a implementação padrão do System.Management.Automation.Provider.ContainerCmdletProvider.RemoveItemDynamicParameters*.

Consulta para Itens Filhos

Para verificar se existem itens filhos no caminho especificado, o fornecedor de contentores PowerShell do Windows deve sobrescrever o método System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems* . Este método retorna true se o item tiver filhos, e false caso contrário. Para um caminho nulo ou vazio, o método considera quaisquer itens no armazenamento de dados como filhos e devolve true.

Aqui está a sobreposição para o método System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems* . Se existirem mais de duas partes de caminho criadas pelo método auxiliar ChunkPath, o método devolve false, pois apenas um contentor de base de dados e um contentor de tabela são definidos. Para mais informações sobre este método auxiliar, consulte o método ChunkPath discutido em Criar um Fornecedor de Itens PowerShell para Windows.

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

return results;

Coisas a Lembrar Sobre a Implementação do HasChildItems

As seguintes condições podem aplicar-se à sua implementação de System.Management.Automation.Provider.ContainerCmdletProvider.HasChildItems*:

Cópia de Itens

Para copiar os itens, o fornecedor do contentor deve implementar o método System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem para suportar chamadas do Copy-Item cmdlet. Este método copia um elemento de dados da localização indicada pelo path parâmetro do cmdlet para a localização indicada pelo copyPath parâmetro. Se o recurse parâmetro for especificado, o método copia todos os sub-contentores. Se o parâmetro não for especificado, o método copia apenas um nível de itens.

Este fornecedor não implementa este método. No entanto, o código seguinte é a implementação padrão do System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem.

Coisas a Lembrar Sobre a Implementação do CopyItem

As seguintes condições podem aplicar-se à sua implementação de System.Management.Automation.Provider.ContainerCmdletProvider.CopyItem:

Anexação de Parâmetros Dinâmicos ao Cmdlet Copy-Item

Por vezes, o Copy-Item cmdlet requer parâmetros adicionais que são especificados dinamicamente em tempo de execução. Para fornecer estes parâmetros dinâmicos, o fornecedor de contentores Windows PowerShell deve implementar o método System.Management.Automation.Provider.ContainerCmdletProvider.CopyItemDynamicParameters* para tratar estes parâmetros. Este método recupera os parâmetros do item no caminho indicado e devolve um objeto com propriedades e campos com atributos de análise semelhantes a uma classe cmdlet ou a um objeto System.Management.Automation.RuntimeDefinedParameterDictionary . O runtime do Windows PowerShell usa o objeto devolvido para adicionar os parâmetros ao Copy-Item cmdlet.

Este fornecedor não implementa este método. No entanto, o código seguinte é a implementação padrão de System.Management.Automation.Provider.ContainerCmdletProvider.CopyItemDynamicParameters*.

Exemplo de código

Para código de exemplo completo, consulte AccessDbProviderSample04 Code Sample.

Construir o Fornecedor Windows PowerShell

Veja Como Registar Cmdlets, Fornecedores e Aplicações Anfitriãs.

Testar o Fornecedor Windows PowerShell

Quando o seu fornecedor de PowerShell para Windows estiver registado no Windows PowerShell, pode testá-lo executando os cmdlets suportados na linha de comandos. Tenha em atenção que o seguinte exemplo de saída utiliza uma base de dados Access fictícia.

  1. Execute o Get-ChildItem cmdlet para recuperar a lista de itens filhos de uma tabela Clientes na base de dados Access.

    Get-ChildItem mydb:customers
    

    A seguinte saída aparece.

    PSPath        : AccessDB::customers
    PSDrive       : mydb
    PSProvider    : System.Management.Automation.ProviderInfo
    PSIsContainer : True
    Data          : System.Data.DataRow
    Name          : Customers
    RowCount      : 91
    Columns       :
    
  2. Execute novamente o Get-ChildItem cmdlet para recuperar os dados de uma tabela.

    (Get-ChildItem mydb:customers).Data
    

    A seguinte saída aparece.

    TABLE_CAT   : C:\PS\northwind
    TABLE_SCHEM :
    TABLE_NAME  : Customers
    TABLE_TYPE  : TABLE
    REMARKS     :
    
  3. Agora use o Get-Item cmdlet para recuperar os itens na linha 0 da tabela de dados.

    Get-Item mydb:\customers\0
    

    A seguinte saída aparece.

    PSPath        : AccessDB::customers\0
    PSDrive       : mydb
    PSProvider    : System.Management.Automation.ProviderInfo
    PSIsContainer : False
    Data          : System.Data.DataRow
    RowNumber     : 0
    
  4. Reutilizar Get-Item para recuperar os dados dos itens da linha 0.

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

    A seguinte saída aparece.

    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. Agora usa o New-Item cmdlet para adicionar uma linha a uma tabela existente. O Path parâmetro especifica o caminho completo até à linha e deve indicar um número de linha maior do que o número existente de linhas na tabela. O Type parâmetro indica Row especificar esse tipo de item a adicionar. Finalmente, o Value parâmetro especifica uma lista delimitada por vírgulas de valores de colunas para a linha.

    New-Item -Path mydb:\Customers\3 -ItemType "Row" -Value "3,CustomerFirstName,CustomerLastName,CustomerEmailAddress,CustomerTitle,CustomerCompany,CustomerPhone, CustomerAddress,CustomerCity,CustomerState,CustomerZip,CustomerCountry"
    
  6. Verifique a correção da operação do novo item da seguinte forma.

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

    A seguinte saída aparece.

    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
    

Ver também

Criação de Fornecedores Windows PowerShell

Desenhar o Seu Fornecedor Windows PowerShell

Implementação de um Item do Fornecedor Windows PowerShell

Implementação de um Fornecedor de Navegação Windows PowerShell

Como Registar Cmdlets, Fornecedores e Aplicações Anfitriãs

Windows PowerShell SDK

Guia do Programador do Windows PowerShell