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.

您可以使用非同步讀取作業來避免這些相依性及其死結可能。 或者,您可以建立兩個執行緒並在個別執行緒上讀取每個資料流程的輸出,以避免死結狀況。

適用於

另請參閱