ProcessStartInfo.RedirectStandardError Propriedade
Definição
Importante
Algumas informações se referem a produtos de pré-lançamento que podem ser substancialmente modificados antes do lançamento. A Microsoft não oferece garantias, expressas ou implícitas, das informações aqui fornecidas.
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.WaitForExit
de . 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.