Compartilhar via


ProcessStartInfo.RedirectStandardError Propriedade

Definição

Obtém ou define um valor que indica se a saída de erro de um aplicativo é gravada no fluxo StandardError.

public:
 property bool RedirectStandardError { bool get(); void set(bool value); };
public bool RedirectStandardError { get; set; }
member this.RedirectStandardError : bool with get, set
Public Property RedirectStandardError As Boolean

Valor da propriedade

true se a saída de erro deve ser gravada StandardError; caso contrário, false. O padrão é false.

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 erro padrão do comando net e o grava no console.

Process^ myProcess = gcnew Process;
ProcessStartInfo^ myProcessStartInfo = gcnew ProcessStartInfo( "net ",String::Concat( "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() );
myProcess->Close();
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());
}
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 grava texto em seu fluxo de erro 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.

Observação

Você deve definir UseShellExecute como false se quiser definir RedirectStandardError como true. Caso contrário, a leitura do StandardError fluxo gerará uma exceção.

O fluxo redirecionado StandardError pode ser lido de forma síncrona ou assíncrona. Métodos como ReadReadLine e ReadToEnd executam 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 o associado Process grave em seu StandardError fluxo ou feche 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.

Observação

O aplicativo que está processando a saída assíncrona deve chamar o Process.WaitForExit método para garantir que o buffer de saída tenha sido liberado.

As 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 causar 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 a 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 que um ao outro conclua uma operação e nenhum deles pode continuar. Você pode evitar deadlocks avaliando dependências entre o processo de chamador e 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;
using System.IO;

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:
//      The last 50 characters in the output stream are:
//      ' 49,800.20%
//      Line 500 of 500 written: 49,900.20%
//'
//
//      Error stream: 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:
'      The last 50 characters in the output stream are:
'      ' 49,800.20%
'      Line 500 of 500 written: 49,900.20%
'
'
'      Error stream: 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.WaitForExitde . Uma condição de deadlock poderá resultar se o processo pai chamar p.WaitForExit antes p.StandardError.ReadToEnd e o processo filho gravar 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 o 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.
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 código C# a seguir, por exemplo, 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 resultará se o processo pai chamar p.StandardOutput.ReadToEnd seguido por p.StandardError.ReadToEnd e o processo filho gravar texto suficiente para preencher seu fluxo de erros. O processo pai aguardaria indefinidamente para que o processo filho fechasse seu StandardOutput fluxo. O processo filho aguardaria indefinidamente para que o pai lesse o 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:
//      ' 49,800.20%
//      Line 500 of 500 written: 49,900.20%
//      '
//
//      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:
'      ' 49,800.20%
'      Line 500 of 500 written: 49,900.20%
'      '
'
'      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.

Aplica-se a

Confira também