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 リダイレクトすることで、プロセスのエラー出力を操作または抑制できます。 たとえば、テキストをフィルター処理したり、別の形式に書式設定したり、コンソールと指定されたログ ファイルの両方に出力を書き込んだりできます。

Note

を にfalse設定UseShellExecuteする場合は、 を に設定RedirectStandardErrorするtrue必要があります。 それ以外の場合、ストリームからの読み取りでは StandardError 例外がスローされます。

リダイレクトされた StandardError ストリームは、同期的または非同期的に読み取ることができます。 などのReadReadLineメソッドは、ReadToEndプロセスのエラー出力ストリームに対して同期読み取り操作を実行します。 これらの同期読み取り操作は、関連付けられている Process がストリームに書き込まれるか、ストリームを StandardError 閉じるまで完了しません。

これに対し、 はストリーム BeginErrorReadLine に対する非同期読み取り操作を StandardError 開始します。 このメソッドは、ストリーム出力に対して指定されたイベント ハンドラーを有効にし、すぐに呼び出し元に戻り、ストリーム出力がイベント ハンドラーに送信されている間に他の作業を実行できます。

Note

非同期出力を処理しているアプリケーションは、 メソッドを Process.WaitForExit 呼び出して、出力バッファーがフラッシュされていることを確認する必要があります。

同期読み取り操作では、ストリームからの呼び出し元の読み取りと、 StandardError そのストリームへの書き込み子プロセスとの間に依存関係が発生します。 これらの依存関係により、デッドロック状態が発生する可能性があります。 呼び出し元は、子プロセスのリダイレクトされたストリームから読み取るときに、子プロセスに依存します。 呼び出し元は、子がストリームに書き込むか、ストリームを閉じるまで読み取り操作を待機します。 子プロセスは、リダイレクトされたストリームを埋めるのに十分なデータを書き込む場合、親に依存します。 子プロセスは、親がフル ストリームから読み取るか、ストリームを閉じるまで、次の書き込み操作を待機します。 デッドロック状態は、呼び出し元と子プロセスが互いに操作の完了を待機し、どちらも続行できない場合に発生します。 呼び出し元と子プロセスの間の依存関係を評価することで、デッドロックを回避できます。

このセクションの最後の 2 つの例では、 メソッドを 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.ReadToEndp.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.

非同期読み取り操作を使用して、これらの依存関係とそのデッドロックの可能性を回避できます。 または、2 つのスレッドを作成し、個別のスレッドで各ストリームの出力を読み取ることで、デッドロック状態を回避できます。

適用対象

こちらもご覧ください