ProcessStartInfo.RedirectStandardError Właściwość
Definicja
Ważne
Niektóre informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany przed wydaniem. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.
Pobiera lub ustawia wartość wskazującą, czy dane wyjściowe błędu aplikacji są zapisywane w strumieniu 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
Wartość właściwości
true
jeśli dane wyjściowe błędu powinny być zapisywane w pliku StandardError; false
w przeciwnym razie . Wartość domyślna to false
.
Przykłady
W poniższym przykładzie użyto net use
polecenia razem z argumentem dostarczonym przez użytkownika, aby zamapować zasób sieciowy. Następnie odczytuje standardowy strumień błędów polecenia net i zapisuje go w konsoli.
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
Uwagi
Process Gdy tekst jest zapisywany w standardowym strumieniu błędów, tekst ten jest zwykle wyświetlany w konsoli programu . Przekierowując StandardError strumień, można manipulować lub pomijać dane wyjściowe błędu procesu. Na przykład możesz filtrować tekst, formatować go inaczej lub zapisywać dane wyjściowe zarówno w konsoli, jak i wyznaczonym pliku dziennika.
Uwaga
Musisz ustawić wartość na UseShellExecutefalse
, jeśli chcesz ustawić RedirectStandardError wartość true
. W przeciwnym razie odczyt strumienia StandardError zgłasza wyjątek.
Przekierowany StandardError strumień można odczytywać synchronicznie lub asynchronicznie. Metody, takie jak Read, ReadLine i ReadToEnd wykonują synchroniczne operacje odczytu na strumieniu danych wyjściowych błędu procesu. Te synchroniczne operacje odczytu nie zakończą się, dopóki skojarzone Process operacje zapisu do strumienia StandardError lub nie zamkną strumienia.
BeginErrorReadLine Natomiast uruchamia operacje odczytu asynchronicznego w strumieniuStandardError. Ta metoda umożliwia wyznaczoną procedurę obsługi zdarzeń dla danych wyjściowych strumienia i natychmiast powraca do obiekt wywołujący, co może wykonać inną pracę, gdy dane wyjściowe strumienia są kierowane do programu obsługi zdarzeń.
Uwaga
Aplikacja, która przetwarza dane wyjściowe asynchroniczne, powinna wywołać metodę Process.WaitForExit , aby upewnić się, że bufor wyjściowy został opróżniony.
Synchroniczne operacje odczytu powodują zależność między odczytem wywołującym ze StandardError strumienia a procesem podrzędnym zapisywania w tym strumieniu. Te zależności mogą powodować zakleszczenia. Gdy obiekt wywołujący odczytuje z przekierowanego strumienia procesu podrzędnego, jest on zależny od elementu podrzędnego. Obiekt wywołujący czeka na operację odczytu, dopóki element podrzędny nie zapisze strumienia lub zamknie strumień. Gdy proces podrzędny zapisuje wystarczająco dużo danych, aby wypełnić przekierowany strumień, jest zależny od elementu nadrzędnego. Proces podrzędny czeka na następną operację zapisu, aż element nadrzędny odczytuje z pełnego strumienia lub zamknie strumień. Warunek zakleszczenia wynika, gdy obiekt wywołujący i proces podrzędny czekają na zakończenie operacji, a żadna z nich nie może kontynuować. Można uniknąć zakleszczenia, oceniając zależności między obiektem wywołującym i procesem podrzędnym.
W dwóch ostatnich przykładach w tej sekcji użyto Start metody , aby uruchomić plik wykonywalny o nazwie Write500Lines.exe. Poniższy przykład zawiera kod źródłowy.
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.
W poniższym przykładzie pokazano, jak odczytać ze strumienia błędu przekierowanego i poczekać na zakończenie procesu podrzędnego. Zapobiega to zakleszczeniom, wywołując przed poleceniem p.StandardError.ReadToEnd
p.WaitForExit
. Warunek zakleszczenia może spowodować, że proces nadrzędny wywołuje p.WaitForExit
proces przed p.StandardError.ReadToEnd
, a proces podrzędny zapisuje wystarczającą ilość tekstu, aby wypełnić przekierowany strumień. Proces nadrzędny będzie czekać na zakończenie procesu podrzędnego przez czas nieokreślony. Proces podrzędny będzie czekał na czas nieokreślony, aby element nadrzędny odczytał z pełnego StandardError strumienia.
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.
Podczas odczytywania całego tekstu z standardowych danych wyjściowych i standardowych strumieni błędów występuje podobny problem. Poniższy kod w języku C#, na przykład, wykonuje operację odczytu w obu strumieniach. Pozwala uniknąć stanu zakleszczenia, wykonując operacje odczytu asynchronicznego w strumieniu StandardError . Warunek zakleszczenia powoduje, że po wywołaniu p.StandardOutput.ReadToEnd
p.StandardError.ReadToEnd
procesu nadrzędnego następuje, a proces podrzędny zapisuje wystarczającą ilość tekstu, aby wypełnić strumień błędu. Proces nadrzędny będzie czekać bezterminowo, aż proces podrzędny zamknie strumień StandardOutput . Proces podrzędny będzie czekał na czas nieokreślony, aby element nadrzędny odczytał z pełnego StandardError strumienia.
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.
Możesz użyć asynchronicznych operacji odczytu, aby uniknąć tych zależności i ich potencjału zakleszczenia. Alternatywnie można uniknąć stanu zakleszczenia, tworząc dwa wątki i odczytując dane wyjściowe każdego strumienia w osobnym wątku.