Partilhar via


Adding Non-Terminating Error Reporting to Your Cmdlet (Adicionar Comunicações de Erros de Não Terminação ao seu Cmdlet)

Os cmdlets podem relatar erros não terminativos chamando o método System.Management.Automation.Cmdlet.WriteError e ainda continuar a operar no objeto de entrada atual ou em outros objetos de pipeline de entrada. Esta seção explica como criar um cmdlet que relata erros não terminativos de seus métodos de processamento de entrada.

Para erros que não terminam (bem como erros de encerramento), o cmdlet deve passar um objeto System.Management.Automation.ErrorRecord identificando o erro. Cada registro de erro é identificado por uma cadeia de caracteres exclusiva chamada "identificador de erro". Além do identificador, a categoria de cada erro é especificada por constantes definidas por um System.Management.Automation.ErrorCategory enumeração. O usuário pode visualizar erros com base em sua categoria, definindo a variável $ErrorView como "CategoryView".

Para obter mais informações sobre registros de erro, consulte Registros de erro do Windows PowerShell.

Definindo o cmdlet

A primeira etapa na criação do cmdlet é sempre nomear o cmdlet e declarar a classe .NET que implementa o cmdlet. Esse cmdlet recupera informações do processo, portanto, o nome do verbo escolhido aqui é "Get". (Quase qualquer tipo de cmdlet capaz de recuperar informações pode processar a entrada da linha de comando.) Para obter mais informações sobre verbos de cmdlet aprovados, consulte Cmdlet Verb Names.

A seguir está a definição para este cmdlet Get-Proc. Os detalhes dessa definição são fornecidos em Creating Your First Cmdlet.

[Cmdlet(VerbsCommon.Get, "proc")]
public class GetProcCommand: Cmdlet
<Cmdlet(VerbsCommon.Get, "Proc")> _
Public Class GetProcCommand
    Inherits Cmdlet

Definição de parâmetros

Se necessário, seu cmdlet deve definir parâmetros para processar a entrada. Este cmdlet Get-Proc define um Name parâmetro conforme descrito em Adicionando parâmetros que processam Command-Line entrada.

Aqui está a declaração de parâmetro para o Name parâmetro deste cmdlet Get-Proc.

[Parameter(
           Position = 0,
           ValueFromPipeline = true,
           ValueFromPipelineByPropertyName = true
)]
[ValidateNotNullOrEmpty]
public string[] Name
{
  get { return processNames; }
  set { processNames = value; }
}
private string[] processNames;
<Parameter(Position:=0, ValueFromPipeline:=True, _
ValueFromPipelineByPropertyName:=True), ValidateNotNullOrEmpty()> _
Public Property Name() As String()
    Get
        Return processNames
    End Get

    Set(ByVal value As String())
        processNames = value
    End Set

End Property

Substituindo métodos de processamento de entrada

Todos os cmdlets devem substituir pelo menos um dos métodos de processamento de entrada fornecidos pela classe System.Management.Automation.Cmdlet. Esses métodos são discutidos em Criando seu primeiro cmdlet.

Observação

Seu cmdlet deve lidar com cada registro da forma mais independente possível.

Este cmdlet Get-Proc substitui o método System.Management.Automation.Cmdlet.ProcessRecord para manipular o parâmetro Name para entrada fornecida pelo usuário ou por um script. Este método obterá os processos para cada nome de processo solicitado ou todos os processos se nenhum nome for fornecido. Os detalhes dessa substituição são fornecidos em Criando seu primeiro cmdlet.

Coisas a lembrar ao relatar erros

O System.Management.Automation.ErrorRecord objeto que o cmdlet passa ao escrever um erro requer uma exceção em seu núcleo. Siga as diretrizes do .NET ao determinar a exceção a ser usada. Basicamente, se o erro for semanticamente igual a uma exceção existente, o cmdlet deverá usar ou derivar dessa exceção. Caso contrário, ele deve derivar uma nova exceção ou hierarquia de exceção diretamente da classe System.Exception.

Ao criar identificadores de erro (acessados por meio da propriedade FullyQualifiedErrorId da classe ErrorRecord), lembre-se do seguinte.

  • Use cadeias de caracteres direcionadas para fins de diagnóstico para que, ao inspecionar o identificador totalmente qualificado, você possa determinar o que é o erro e de onde ele veio.

  • Um identificador de erro totalmente qualificado bem formado pode ser o seguinte.

    CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand

Observe que, no exemplo anterior, o identificador de erro (o primeiro token) designa o que é o erro e a parte restante indica de onde o erro veio.

  • Para cenários mais complexos, o identificador de erro pode ser um token separado por pontos que pode ser analisado na inspeção. Isso permite que você também ramificar nas partes do identificador de erro, bem como o identificador de erro e a categoria de erro.

O cmdlet deve atribuir identificadores de erro específicos a caminhos de código diferentes. Tenha em mente as seguintes informações para a atribuição de identificadores de erro:

  • Um identificador de erro deve permanecer constante durante todo o ciclo de vida do cmdlet. Não altere a semântica de um identificador de erro entre versões de cmdlet.
  • Use texto para um identificador de erro que corresponda perfeitamente ao erro que está sendo relatado. Não use espaço em branco ou pontuação.
  • Faça com que seu cmdlet gere apenas identificadores de erro reproduzíveis. Por exemplo, não deve gerar um identificador que inclua um identificador de processo. Os identificadores de erro são úteis para um usuário somente quando correspondem a identificadores que são vistos por outros usuários que enfrentam o mesmo problema.

As exceções não tratadas não são capturadas pelo PowerShell nas seguintes condições:

  • Se um cmdlet criar um novo thread e o código em execução nesse thread gerar uma exceção não tratada, o PowerShell não detetará o erro e encerrará o processo.
  • Se um objeto tiver código em seus métodos destructor ou Dispose que cause uma exceção não tratada, o PowerShell não detetará o erro e encerrará o processo.

Relatar erros não terminativos

Qualquer um dos métodos de processamento de entrada pode relatar um erro não terminativo para o fluxo de saída usando o método System.Management.Automation.Cmdlet.WriteError.

Aqui está um exemplo de código deste cmdlet Get-Proc que ilustra a chamada para System.Management.Automation.Cmdlet.WriteError de dentro da substituição do método System.Management.Automation.Cmdlet.ProcessRecord. Nesse caso, a chamada será feita se o cmdlet não conseguir encontrar um processo para um identificador de processo especificado.

protected override void ProcessRecord()
{
  // If no name parameter passed to cmdlet, get all processes.
  if (processNames == null)
  {
    WriteObject(Process.GetProcesses(), true);
  }
    else
    {
      // If a name parameter is passed to cmdlet, get and write
      // the associated processes.
      // Write a non-terminating error for failure to retrieve
      // a process.
      foreach (string name in processNames)
      {
        Process[] processes;

        try
        {
          processes = Process.GetProcessesByName(name);
        }
        catch (InvalidOperationException ex)
        {
          WriteError(new ErrorRecord(
                     ex,
                     "NameNotFound",
                     ErrorCategory.InvalidOperation,
                     name));
          continue;
        }

        WriteObject(processes, true);
      } // foreach (...
    } // else
  }

Coisas a lembrar sobre erros de escrita que não terminam

Para um erro não terminativo, o cmdlet deve gerar um identificador de erro específico para cada objeto de entrada específico.

Um cmdlet frequentemente precisa modificar a ação do PowerShell produzida por um erro de não terminação. Pode fazê-lo definindo os parâmetros ErrorAction e ErrorVariable. Se definir o parâmetro ErrorAction, o cmdlet apresentará as opções do usuário System.Management.Automation.ActionPreference, você também poderá influenciar diretamente a ação definindo a variável $ErrorActionPreference.

O cmdlet pode salvar erros não terminativos em uma variável usando o parâmetro ErrorVariable, que não é afetado pela configuração de ErrorAction. As falhas podem ser acrescentadas a uma variável de erro existente adicionando um sinal de adição (+) à frente do nome da variável.

Exemplo de código

Para obter o código de exemplo C# completo, consulte GetProcessSample04 Sample.

Definir tipos de objeto e formatação

O PowerShell passa informações entre cmdlets usando objetos .NET. Consequentemente, um cmdlet pode precisar definir seu próprio tipo, ou o cmdlet pode precisar estender um tipo existente fornecido por outro cmdlet. Para obter mais informações sobre como definir novos tipos ou estender tipos existentes, consulte Estendendo tipos de objeto e formatando.

Criando o cmdlet

Depois de implementar um cmdlet, você deve registrá-lo com o Windows PowerShell por meio de um snap-in do Windows PowerShell. Para obter mais informações sobre como registrar cmdlets, consulte Como registrar cmdlets, provedores e aplicativos host.

Testando o cmdlet

Quando seu cmdlet tiver sido registrado no PowerShell, você poderá testá-lo executando-o na linha de comando. Vamos testar o cmdlet Get-Proc de exemplo para ver se ele relata um erro:

  • Inicie o PowerShell e use o cmdlet Get-Proc para recuperar os processos chamados "TEST".

    Get-Proc -Name test
    

    A saída a seguir é exibida.

    Get-Proc : Operation is not valid due to the current state of the object.
    At line:1 char:9
    + Get-Proc  <<<< -Name test
    

Ver também