Process.StandardError Propriedade

Definição

Obtém um fluxo usado para ler a saída de erro do aplicativo.

public:
 property System::IO::StreamReader ^ StandardError { System::IO::StreamReader ^ get(); };
[System.ComponentModel.Browsable(false)]
public System.IO.StreamReader StandardError { get; }
[<System.ComponentModel.Browsable(false)>]
member this.StandardError : System.IO.StreamReader
Public ReadOnly Property StandardError As StreamReader

Valor da propriedade

Um StreamReader que pode ser usado para ler o fluxo de erros padrão do aplicativo.

Atributos

Exceções

O StandardError fluxo não foi definido para redirecionamento; verifique se RedirectStandardError está definido true como e UseShellExecute está definido como false.

-ou-

O StandardError fluxo foi aberto para operações de leitura assíncronas com BeginErrorReadLine().

Exemplos

O exemplo a seguir usa o net use comando junto com um argumento fornecido pelo usuário para mapear um recurso de rede. Em seguida, ele lê o fluxo de erros padrão do comando net e grava-o no console.

using (Process myProcess = new Process())
{
    ProcessStartInfo myProcessStartInfo = new ProcessStartInfo("net ", "use " + args[0]);

    myProcessStartInfo.UseShellExecute = false;
    myProcessStartInfo.RedirectStandardError = true;
    myProcess.StartInfo = myProcessStartInfo;
    myProcess.Start();

    StreamReader myStreamReader = myProcess.StandardError;
    // Read the standard error of net.exe and write it on to console.
    Console.WriteLine(myStreamReader.ReadLine());
}
use myProcess = new Process()
let myProcessStartInfo = ProcessStartInfo("net ", $"use {args[0]}")

myProcessStartInfo.UseShellExecute <- false
myProcessStartInfo.RedirectStandardError <- true
myProcess.StartInfo <- myProcessStartInfo
myProcess.Start() |> ignore

let myStreamReader = myProcess.StandardError
// Read the standard error of net.exe and write it on to console.
printfn $"{myStreamReader.ReadLine()}"
Using myProcess As New Process()
    Dim myProcessStartInfo As New ProcessStartInfo("net ", "use " + args(0))

    myProcessStartInfo.UseShellExecute = False
    myProcessStartInfo.RedirectStandardError = True
    myProcess.StartInfo = myProcessStartInfo
    myProcess.Start()

    Dim myStreamReader As StreamReader = myProcess.StandardError
    ' Read the standard error of net.exe and write it on to console.
    Console.WriteLine(myStreamReader.ReadLine())
End Using

Comentários

Quando um Process texto é gravado em seu fluxo de erros padrão, esse texto normalmente é exibido no console. Ao redirecionar o StandardError fluxo, você pode manipular ou suprimir a saída de erro de um processo. Por exemplo, você pode filtrar o texto, formatá-lo de forma diferente ou gravar a saída no console e em um arquivo de log designado.

Note

Para usar StandardError, você deve definir ProcessStartInfo.UseShellExecute como false, e você deve definir ProcessStartInfo.RedirectStandardError como true. Caso contrário, a leitura do StandardError fluxo gera uma exceção.

O fluxo redirecionado StandardError pode ser lido de forma síncrona ou assíncrona. Métodos como Read, ReadLinee ReadToEnd executar operações de leitura síncronas no fluxo de saída de erro do processo. Essas operações de leitura síncronas não são concluídas até que as gravações associadas Process em seu StandardError fluxo ou fechem o fluxo.

Por outro lado, BeginErrorReadLine inicia operações de leitura assíncronas no StandardError fluxo. Esse método habilita um manipulador de eventos designado para a saída do fluxo e retorna imediatamente ao chamador, que pode executar outro trabalho enquanto a saída do fluxo é direcionada para o manipulador de eventos.

Operações de leitura síncronas introduzem uma dependência entre a leitura do chamador do StandardError fluxo e o processo filho que está gravando nesse fluxo. Essas dependências podem resultar em condições de deadlock. Quando o chamador lê do fluxo redirecionado de um processo filho, ele depende do filho. O chamador aguarda a operação de leitura até que o filho grave no fluxo ou feche o fluxo. Quando o processo filho grava dados suficientes para preencher seu fluxo redirecionado, ele depende do pai. O processo filho aguarda na próxima operação de gravação até que o pai leia do fluxo completo ou feche o fluxo. A condição de deadlock resulta quando o chamador e o processo filho esperam um pelo outro para concluir uma operação e nenhum deles pode continuar. Você pode evitar deadlocks avaliando as dependências entre o chamador e o processo filho.

Os dois últimos exemplos nesta seção usam o Start método para iniciar um executável chamado Write500Lines.exe. O exemplo a seguir contém seu código-fonte.

using System;

public class Example3
{
    public static void Main()
    {
        for (int ctr = 0; ctr < 500; ctr++)
            Console.WriteLine($"Line {ctr + 1} of 500 written: {(ctr + 1) / 500.0:P2}");

        Console.Error.WriteLine("\nSuccessfully wrote 500 lines.\n");
    }
}
// The example displays the following output:
//      Line 1 of 500 written: 0,20%
//      Line 2 of 500 written: 0,40%
//      Line 3 of 500 written: 0,60%
//      ...
//      Line 498 of 500 written: 99,60%
//      Line 499 of 500 written: 99,80%
//      Line 500 of 500 written: 100,00%
//
//      Successfully wrote 500 lines.
module Write500Lines

for i in 1. .. 500. do
    printfn $"Line {i} of 500 written: {i/500.:P2}";

eprintfn "Successfully wrote 500 lines.";
// The example displays the following output:
//      Line 1 of 500 written: 0,20%
//      Line 2 of 500 written: 0,40%
//      Line 3 of 500 written: 0,60%
//      ...
//      Line 498 of 500 written: 99,60%
//      Line 499 of 500 written: 99,80%
//      Line 500 of 500 written: 100,00%
//      Successfully wrote 500 lines.
Imports System.IO

Public Module Example
   Public Sub Main()
      For ctr As Integer = 0 To 499
         Console.WriteLine($"Line {ctr + 1} of 500 written: {(ctr + 1) / 500.0:P2}")
      Next

      Console.Error.WriteLine($"{vbCrLf}Successfully wrote 500 lines.{vbCrLf}")
   End Sub
End Module
' The example displays the following output:
'      Line 1 of 500 written 0,20%
'      Line 2 of 500 written: 0,40%
'      Line 3 of 500 written: 0,60%
'      ...
'      Line 498 of 500 written: 99,60%
'      Line 499 of 500 written: 99,80%
'      Line 500 of 500 written: 100,00%
'
'      Successfully wrote 500 lines.

O exemplo a seguir mostra como ler de um fluxo de erros redirecionado e aguardar a saída do processo filho. Ele evita uma condição de deadlock chamando p.StandardError.ReadToEnd antes p.WaitForExit. Uma condição de deadlock pode resultar se o processo pai chama p.WaitForExit antes p.StandardError.ReadToEnd e o processo filho grava texto suficiente para preencher o fluxo redirecionado. O processo pai aguardaria indefinidamente a saída do processo filho. O processo filho aguardaria indefinidamente para que o pai lesse do fluxo completo StandardError .

using System;
using System.Diagnostics;

public class Example
{
   public static void Main()
   {
      var p = new Process();  
      p.StartInfo.UseShellExecute = false;  
      p.StartInfo.RedirectStandardError = true;  
      p.StartInfo.FileName = "Write500Lines.exe";  
      p.Start();  

      // To avoid deadlocks, always read the output stream first and then wait.  
      string output = p.StandardError.ReadToEnd();  
      p.WaitForExit();

      Console.WriteLine($"\nError stream: {output}");
   }
}
// The end of the output produced by the example includes the following:
//      Error stream:
//      Successfully wrote 500 lines.
module STDErrorSync

open System.Diagnostics

let p = new Process()
p.StartInfo.UseShellExecute <- false
p.StartInfo.RedirectStandardError <- true
p.StartInfo.FileName <- "Write500Lines.exe"
p.Start() |> ignore

// To avoid deadlocks, always read the output stream first and then wait.
let output = p.StandardError.ReadToEnd()
p.WaitForExit()

printfn $"\nError stream: {output}"
// The end of the output produced by the example includes the following:
//      Error stream:
//      Successfully wrote 500 lines.
Imports System.Diagnostics

Public Module Example
    Public Sub Main()
        Dim p As New Process()
        p.StartInfo.UseShellExecute = False  
        p.StartInfo.RedirectStandardError = True  
        p.StartInfo.FileName = "Write500Lines.exe"  
        p.Start() 

        ' To avoid deadlocks, always read the output stream first and then wait.  
        Dim output As String = p.StandardError.ReadToEnd()  
        p.WaitForExit()

        Console.WriteLine($"{vbCrLf}Error stream: {output}")
    End Sub
End Module
' The end of the output produced by the example includes the following:
'      Error stream:
'      Successfully wrote 500 lines.

Há um problema semelhante quando você lê todo o texto dos fluxos de erro padrão e de saída padrão. O exemplo a seguir executa uma operação de leitura em ambos os fluxos. Ele evita a condição de deadlock executando operações de leitura assíncronas no StandardError fluxo. Uma condição de deadlock resulta se o processo pai chama p.StandardOutput.ReadToEnd seguido p.StandardError.ReadToEnd e o processo filho grava texto suficiente para preencher seu fluxo de erros. O processo pai aguardaria indefinidamente o processo filho fechar seu StandardOutput fluxo. O processo filho aguardaria indefinidamente para que o pai lesse do fluxo completo StandardError .

using System;
using System.Diagnostics;

public class Example
{
    public static void Main()
    {
        var p = new Process();
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.RedirectStandardOutput = true;
        string eOut = null;
        p.StartInfo.RedirectStandardError = true;
        p.ErrorDataReceived += new DataReceivedEventHandler((sender, e) =>
                                   { eOut += e.Data; });
        p.StartInfo.FileName = "Write500Lines.exe";
        p.Start();

        // To avoid deadlocks, use an asynchronous read operation on at least one of the streams.  
        p.BeginErrorReadLine();
        string output = p.StandardOutput.ReadToEnd();
        p.WaitForExit();

        Console.WriteLine($"The last 50 characters in the output stream are:\n'{output.Substring(output.Length - 50)}'");
        Console.WriteLine($"\nError stream: {eOut}");
    }
}
// The example displays the following output:
//      The last 50 characters in the output stream are:
//      'ritten: 99,80%
//      Line 500 of 500 written: 100,00%
//      '
//
//      Error stream: Successfully wrote 500 lines.
module STDOutputAsync

open System.Diagnostics

let p = new Process()
p.StartInfo.UseShellExecute <- false
p.StartInfo.RedirectStandardOutput <- true
let mutable eOut = ""
p.StartInfo.RedirectStandardError <- true
p.ErrorDataReceived.AddHandler(DataReceivedEventHandler(fun sender e -> eOut <- eOut + e.Data))

p.StartInfo.FileName <- "Write500Lines.exe"
p.Start() |> ignore

// To avoid deadlocks, use an asynchronous read operation on at least one of the streams.
p.BeginErrorReadLine()
let output = p.StandardOutput.ReadToEnd()
p.WaitForExit()

printfn $"The last 50 characters in the output stream are:\n'{output.Substring(output.Length - 50)}'"
printfn $"\nError stream: {eOut}"
// The example displays the following output:
//      The last 50 characters in the output stream are:
//      'ritten: 99,80%
//      Line 500 of 500 written: 100,00%
//      '
//
//      Error stream: Successfully wrote 500 lines.
Imports System.Diagnostics

Public Module Example
   Public Sub Main()
      Dim p As New Process()  
      p.StartInfo.UseShellExecute = False  
      p.StartInfo.RedirectStandardOutput = True  
      Dim eOut As String = Nothing
      p.StartInfo.RedirectStandardError = True
      AddHandler p.ErrorDataReceived, Sub(sender, e) eOut += e.Data 
      p.StartInfo.FileName = "Write500Lines.exe"  
      p.Start()  

      ' To avoid deadlocks, use an asynchronous read operation on at least one of the streams.  
      p.BeginErrorReadLine()
      Dim output As String = p.StandardOutput.ReadToEnd()  
      p.WaitForExit()

      Console.WriteLine($"The last 50 characters in the output stream are:{vbCrLf}'{output.Substring(output.Length - 50)}'")
      Console.WriteLine($"{vbCrLf}Error stream: {eOut}")
   End Sub
End Module
' The example displays the following output:
'      The last 50 characters in the output stream are:
'      'ritten: 99,80%
'      Line 500 of 500 written: 100,00%
'      '
'
'      Error stream: Successfully wrote 500 lines.

Você pode usar operações de leitura assíncronas para evitar essas dependências e seu potencial de deadlock. Como alternativa, você pode evitar a condição de deadlock criando dois threads e lendo a saída de cada fluxo em um thread separado.

Note

Não é possível misturar operações de leitura assíncronas e síncronas em um fluxo redirecionado. Depois que o fluxo redirecionado de um Process for aberto no modo assíncrono ou síncrono, todas as operações de leitura adicionais nesse fluxo deverão estar no mesmo modo. Por exemplo, não siga BeginErrorReadLine com uma chamada para ReadLine o StandardError fluxo ou vice-versa. No entanto, você pode ler dois fluxos diferentes em modos diferentes. Por exemplo, você pode ligar BeginOutputReadLine e chamar ReadLine o StandardError fluxo.

Aplica-se a

Confira também