ProcessStartInfo.RedirectStandardError 屬性

定義

取得或設定值,表示應用程式的錯誤輸出是否寫入至 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

屬性值

如果錯誤輸出應該寫入至 StandardError,則為 true,否則為 false。 預設為 false

範例

下列範例會 net use 搭配使用者提供的自變數使用 命令來對應網路資源。 然後,它會讀取 net 命令的標準錯誤數據流,並將它寫入主控台。

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

備註

Process當 將文字寫入至其標準錯誤數據流時,該文字通常會顯示在控制臺上。 藉由重新導向 StandardError 數據流,您可以操作或隱藏進程的錯誤輸出。 例如,您可以篩選文字、以不同的方式格式化,或將輸出寫入主控台和指定的記錄檔。

注意

如果您想要設定為 ,則必須將 設定UseShellExecutefalseRedirectStandardError為。true 否則,從 StandardError 數據流讀取會擲回例外狀況。

重新導向 StandardError 的數據流可以同步或異步讀取。 例如 Read的方法, ReadLine 並在 ReadToEnd 進程的錯誤輸出數據流上執行同步讀取作業。 這些同步讀取作業在相關聯的 Process 數據流寫入 StandardError 或關閉數據流之前不會完成。

相反地, BeginErrorReadLine 會啟動數據流上的 StandardError 異步讀取作業。 這個方法會啟用數據流輸出的指定事件處理程式,並立即傳回給呼叫端,這可以在數據流輸出導向事件處理程式時執行其他工作。

注意

處理異步輸出的應用程式應該呼叫 Process.WaitForExit 方法,以確保已排清輸出緩衝區。

同步讀取作業引進從 StandardError 數據流讀取的呼叫端與寫入該數據流的子進程之間的相依性。 這些相依性可能會導致死結狀況。 當呼叫端從子進程的重新導向數據流讀取時,它會相依於子進程。 呼叫端會等候讀取作業,直到子系寫入數據流或關閉數據流為止。 當子進程寫入足夠的數據以填滿其重新導向的數據流時,其相依於父代。 子進程會等候下一個寫入作業,直到父系從完整數據流讀取或關閉數據流為止。 當呼叫端和子進程等候彼此完成作業時,死結條件會產生,而且兩者都無法繼續。 您可以藉由評估呼叫端與子進程之間的相依性,以避免死結。

本節的最後兩個範例會 Start 使用 方法來啟動名為 Write500Lines.exe的可執行檔。 下列範例包含其原始程式碼。

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.

下列範例示範如何從重新導向的錯誤數據流讀取,並等候子進程結束。 它會在 之前p.WaitForExit呼叫 p.StandardError.ReadToEnd 來避免死結狀況。 如果父進程在 之前p.StandardError.ReadToEnd呼叫 p.WaitForExit ,且子進程會寫入足夠的文字來填滿重新導向數據流,則死結條件可能會產生。 父進程會無限期等候子進程結束。 子進程會無限期地等候父代從完整 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.

當您從標準輸出和標準錯誤數據流讀取所有文字時,會有類似的問題。 例如,下列 C# 程式代碼會在這兩個數據流上執行讀取作業。 它會在數據流上 StandardError 執行異步讀取作業,以避免死結狀況。 如果父行程呼叫 p.StandardOutput.ReadToEnd 後面接著 p.StandardError.ReadToEnd ,且子進程會寫入足夠的文字來填滿其錯誤數據流,則死結條件會產生。 父進程會無限期等候子進程關閉其 StandardOutput 數據流。 子進程會無限期地等候父代從完整 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.

您可以使用異步讀取作業來避免這些相依性及其死結可能。 或者,您可以建立兩個線程並在個別線程上讀取每個數據流的輸出,以避免死結狀況。

適用於

另請參閱