Adicionar relatórios de erros de não encerramento ao seu cmdlet
Os cmdlets podem relatar erros de não terminação chamando o método System.Management.Automation.Cmdlet.WriteError e ainda continuar operando no objeto de entrada atual ou em outros objetos de pipeline de entrada. Esta seção explica como criar um cmdlet que relata erros de não encerramento de seus métodos de processamento de entrada.
Para erros de não término (bem como erros de encerramento), o cmdlet deve passar um objeto System.Management.Automation.ErrorRecord que identifica 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 exibir erros com base em sua categoria definindo a variável $ErrorView
como "CategoryView".
Para obter mais informações sobre registros de erros, consulte Registros de Erros 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 é "Obter". (Quase qualquer tipo de cmdlet capaz de recuperar informações pode processar entrada de linha de comando.) Para obter mais informações sobre verbos de cmdlet aprovados, consulte Nomes de Verbo do Cmdlet.
Veja a seguir a definição deste cmdlet Get-Proc
. Os detalhes dessa definição são dados em Criando seu primeiro cmdlet.
[Cmdlet(VerbsCommon.Get, "proc")]
public class GetProcCommand: Cmdlet
<Cmdlet(VerbsCommon.Get, "Proc")> _
Public Class GetProcCommand
Inherits Cmdlet
Definindo parâmetros
Se necessário, seu cmdlet deve definir parâmetros para processamento de entrada. Esse cmdlet Get-Proc define um parâmetro Name, conforme descrito em Adicionando parâmetros que processamde entrada de Command-Line.
Aqui está a declaração de parâmetro do parâmetro Name 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 manipular cada registro da maneira mais independente possível.
Esse cmdlet Get-Proc substitui o método System.Management.Automation.Cmdlet.ProcessRecord para lidar com o parâmetro nome para entrada fornecida pelo usuário ou um script. Esse 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 dados em Criando seu primeiro cmdlet.
Coisas para lembrar ao relatar erros
O objeto System.Management.Automation.ErrorRecord 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 o mesmo que uma exceção existente, o cmdlet deverá usar ou derivar dessa exceção. Caso contrário, ele deverá 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) tenha o seguinte em mente.
Use cadeias de caracteres direcionadas para fins de diagnóstico para que, ao inspecionar o identificador totalmente qualificado, você possa determinar qual é o erro e de onde o erro 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 ponto que pode ser analisado na inspeção. Isso permite que você também branch 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 as seguintes informações em mente para 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 as versões do cmdlet.
- Use o texto para um identificador de erro que corresponda ao erro que está sendo relatado. Não use espaço em branco ou pontuação.
- Faça com que o cmdlet gere apenas identificadores de erro reproduzíveis. Por exemplo, ele não deve gerar um identificador que inclua um identificador de processo. Identificadores de erro são úteis para um usuário somente quando correspondem a identificadores que são vistos por outros usuários com o mesmo problema.
Exceções sem tratamento não são capturadas pelo PowerShell nas seguintes condições:
- Se um cmdlet criar um novo thread e código em execução nesse thread gerar uma exceção sem tratamento, o PowerShell não detectará o erro e encerrará o processo.
- Se um objeto tiver código em seu destruidor ou métodos Dispose que causem uma exceção sem tratamento, o PowerShell não detectará o erro e encerrará o processo.
Relatando erros de não terminação
Qualquer um dos métodos de processamento de entrada pode relatar um erro de não encerramento 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 puder 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 serem lembradas sobre como escrever erros de não terminação
Para um erro de não encerramento, 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. Ele pode fazer isso definindo os parâmetros ErrorAction
e ErrorVariable
. Se definir o parâmetro ErrorAction
, o cmdlet apresentará as opções de 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 de não terminação 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 em C# completo, consulte de exemplo GetProcessSample04.
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 formatação.
Compilando o cmdlet
Depois de implementar um cmdlet, você deve registrá-lo no 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 o 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
Consulte Também
a adição de parâmetros que processam de entrada de pipeline
adicionando parâmetros que processam de entrada de Command-Line