ProcessStartInfo.RedirectStandardOutput プロパティ

定義

アプリケーションのテキスト出力を StandardOutput ストリームに書き込むかどうかを示す値を取得または設定します。

public:
 property bool RedirectStandardOutput { bool get(); void set(bool value); };
public bool RedirectStandardOutput { get; set; }
member this.RedirectStandardOutput : bool with get, set
Public Property RedirectStandardOutput As Boolean

プロパティ値

Boolean

出力を StandardOutput に書き込む場合は true。それ以外の場合は false。 既定値は、false です。

// Run "cl.exe /cld stdstr.cpp /link /out:sample.exe". UseShellExecute is false because we're specifying
// an executable directly and in this case depending on it being in a PATH folder. By setting
// RedirectStandardOutput to true, the output of cl.exe is directed to the Process.StandardOutput stream
// which is then displayed in this console window directly.    
Process^ compiler = gcnew Process;
compiler->StartInfo->FileName = "cl.exe";
compiler->StartInfo->Arguments = "/clr stdstr.cpp /link /out:sample.exe";
compiler->StartInfo->UseShellExecute = false;
compiler->StartInfo->RedirectStandardOutput = true;
compiler->Start();

Console::WriteLine( compiler->StandardOutput->ReadToEnd() );

compiler->WaitForExit();
// Run "csc.exe /r:System.dll /out:sample.exe stdstr.cs". UseShellExecute is false because we're specifying
// an executable directly and in this case depending on it being in a PATH folder. By setting
// RedirectStandardOutput to true, the output of csc.exe is directed to the Process.StandardOutput stream
// which is then displayed in this console window directly.
using (Process compiler = new Process())
{
    compiler.StartInfo.FileName = "csc.exe";
    compiler.StartInfo.Arguments = "/r:System.dll /out:sample.exe stdstr.cs";
    compiler.StartInfo.UseShellExecute = false;
    compiler.StartInfo.RedirectStandardOutput = true;
    compiler.Start();

    Console.WriteLine(compiler.StandardOutput.ReadToEnd());

    compiler.WaitForExit();
}
' Run "vbc.exe /reference:Microsoft.VisualBasic.dll /out:sample.exe stdstr.vb". UseShellExecute is False 
' because we're specifying an executable directly and in this case depending on it being in a PATH folder. 
' By setting RedirectStandardOutput to True, the output of csc.exe is directed to the Process.StandardOutput 
' stream which is then displayed in this console window directly.    
Using compiler As New Process()
    compiler.StartInfo.FileName = "vbc.exe"
    compiler.StartInfo.Arguments = "/reference:Microsoft.VisualBasic.dll /out:sample.exe stdstr.vb"
    compiler.StartInfo.UseShellExecute = False
    compiler.StartInfo.RedirectStandardOutput = True
    compiler.Start()

    Console.WriteLine(compiler.StandardOutput.ReadToEnd())

    compiler.WaitForExit()
End Using

注釈

Process標準ストリームにテキストを書き込むとき、そのテキストは通常コンソールに表示されます。 ストリームをリダイレクトStandardOutputするようにtrue設定RedirectStandardOutputすると、プロセスの出力を操作または抑制できます。 たとえば、テキストをフィルター処理したり、別の形式にしたり、コンソールと指定されたログ ファイルの両方に出力を書き込んだりできます。

注意

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

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

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

注意

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

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

このセクションの最後の 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.StandardOutput.ReadToEndすことでデッドロック状態を回避します。 デッドロック状態は、親プロセスが前にp.StandardOutput.ReadToEnd呼び出p.WaitForExitし、子プロセスがリダイレクトされたストリームを満たすのに十分なテキストを書き込む場合に発生する可能性があります。 親プロセスは、子プロセスが終了するまで無期限に待機します。 子プロセスは、親がフル StandardOutput ストリームから読み取るのを無期限に待機します。

using System;
using System.Diagnostics;

public class Example2
{
   public static void Main()
   {
      var p = new Process();  
      p.StartInfo.UseShellExecute = false;  
      p.StartInfo.RedirectStandardOutput = true;  
      p.StartInfo.FileName = "Write500Lines.exe";  
      p.Start();  

      // To avoid deadlocks, always read the output stream first and then wait.  
      string output = p.StandardOutput.ReadToEnd();  
      p.WaitForExit();

      Console.WriteLine($"The last 50 characters in the output stream are:\n'{output.Substring(output.Length - 50)}'");
   }
}
// The example displays the following output:
//      Successfully wrote 500 lines.
//
//      The last 50 characters in the output stream are:
//      ' 49,800.20%
//      Line 500 of 500 written: 49,900.20%
//      '
Imports System.Diagnostics'

Public Module Example
   Public Sub Main()
      Dim p As New Process()
      p.StartInfo.UseShellExecute = False  
      p.StartInfo.RedirectStandardOutput = 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.StandardOutput.ReadToEnd()  
      p.WaitForExit()

      Console.WriteLine($"The last 50 characters in the output stream are:\n'{output.Substring(output.Length - 50)}'")
   End Sub
End Module
' The example displays the following output:
'      Successfully wrote 500 lines.
'
'      The last 50 characters in the output stream are:
'      ' 49,800.20%
'      Line 500 of 500 written: 49,900.20%
'      '

標準出力ストリームと標準エラー ストリームの両方からすべてのテキストを読み取ると、同様の問題が発生します。 次の例では、両方のストリームに対して読み取り操作を実行します。 ストリームに対して非同期読み取り操作を実行することで、デッドロック状態を StandardError 回避します。 デッドロック状態は、親プロセスがその後p.StandardError.ReadToEndに呼び出p.StandardOutput.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 つのスレッドを作成し、個別のスレッドで各ストリームの出力を読み取ることで、デッドロック状態を回避できます。

適用対象

こちらもご覧ください