ProcessStartInfo.RedirectStandardOutput プロパティ
定義
重要
一部の情報は、リリース前に大きく変更される可能性があるプレリリースされた製品に関するものです。 Microsoft は、ここに記載されている情報について、明示または黙示を問わず、一切保証しません。
アプリケーションのテキスト出力が 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
プロパティ値
true 出力を StandardOutputに書き込む必要がある場合は !。それ以外の場合は false。 既定値は false です。
例
// 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が標準ストリームにテキストを書き込むと、通常、そのテキストがコンソールに表示されます。
RedirectStandardOutputをtrueに設定してStandardOutput ストリームをリダイレクトすることで、プロセスの出力を操作または抑制できます。 たとえば、テキストをフィルター処理したり、別の形式で書式設定したり、コンソールと指定されたログ ファイルの両方に出力を書き込んだりできます。
Note
UseShellExecuteを false に設定する場合は、RedirectStandardOutputを true に設定する必要があります。 それ以外の場合、 StandardOutput ストリームからの読み取りでは例外がスローされます。
リダイレクトされた StandardOutput ストリームは、同期的または非同期的に読み取ることができます。 Read、ReadLine、ReadToEndなどのメソッドは、プロセスの出力ストリームに対して同期読み取り操作を実行します。 これらの同期読み取り操作は、関連付けられている Process が StandardOutput ストリームに書き込むか、ストリームを閉じるまで完了しません。
これに対し、 BeginOutputReadLine は、 StandardOutput ストリームに対する非同期読み取り操作を開始します。 このメソッドは、ストリーム出力に対して指定されたイベント ハンドラー ( OutputDataReceivedを参照) を有効にし、すぐに呼び出し元に戻ります。呼び出し元は、ストリーム出力がイベント ハンドラーに送信されている間に他の作業を実行できます。
Note
非同期出力を処理しているアプリケーションは、 WaitForExit メソッドを呼び出して、出力バッファーがフラッシュされていることを確認する必要があります。
同期読み取り操作では、 StandardOutput ストリームからの呼び出し元の読み取りと、そのストリームへの子プロセスの書き込みの間に依存関係が発生します。 これらの依存関係により、デッドロック状態が発生する可能性があります。 呼び出し元が子プロセスのリダイレクトされたストリームから読み取る場合、呼び出し元は子プロセスに依存します。 呼び出し元は、子がストリームに書き込むか、ストリームを閉じるまで、読み取り操作を待機します。 子プロセスが、リダイレクトされたストリームを満たすのに十分なデータを書き込むときは、親に依存します。 子プロセスは、親が完全なストリームから読み取るか、ストリームを閉じるまで、次の書き込み操作を待機します。 デッドロック状態は、呼び出し元と子プロセスが互いに操作を完了するのを待機し、どちらも続行できない場合に発生します。 呼び出し元と子プロセスの間の依存関係を評価することで、デッドロックを回避できます。
このセクションの最後の 2 つの例では、 Start メソッドを使用して 、Write500Lines.exeという名前の実行可能ファイルを起動します。 次の例には、そのソース コードが含まれています。
using System;
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:
// Line 1 of 500 written: 0,20%
// Line 2 of 500 written: 0,40%
// Line 3 of 500 written: 0,60%
// ...
// Line 498 of 500 written: 99,60%
// Line 499 of 500 written: 99,80%
// Line 500 of 500 written: 100,00%
//
// 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:
' Line 1 of 500 written 0,20%
' Line 2 of 500 written: 0,40%
' Line 3 of 500 written: 0,60%
' ...
' Line 498 of 500 written: 99,60%
' Line 499 of 500 written: 99,80%
' Line 500 of 500 written: 100,00%
'
' Successfully wrote 500 lines.
次の例は、リダイレクトされたストリームから読み取り、子プロセスが終了するまで待機する方法を示しています。 この例では、p.StandardOutput.ReadToEndする前に p.WaitForExit を呼び出すことによってデッドロック状態を回避します。 親プロセスがp.WaitForExitする前にp.StandardOutput.ReadToEndを呼び出し、子プロセスがリダイレクトされたストリームを埋めるのに十分なテキストを書き込む場合、デッドロック状態が発生する可能性があります。 親プロセスは、子プロセスが終了するまで無期限に待機します。 子プロセスは、親が完全な 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:
// 'ritten: 99,80%
// Line 500 of 500 written: 100,00%
// '
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:
' 'ritten: 99,80%
' Line 500 of 500 written: 100,00%
' '
標準出力ストリームと標準エラー ストリームの両方からすべてのテキストを読み取ると、同様の問題があります。 次の例では、両方のストリームで読み取り操作を実行します。
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:
// 'ritten: 99,80%
// Line 500 of 500 written: 100,00%
// '
//
// 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:
' 'ritten: 99,80%
' Line 500 of 500 written: 100,00%
' '
'
' Error stream: Successfully wrote 500 lines.
非同期読み取り操作を使用して、これらの依存関係とそのデッドロックの可能性を回避できます。 または、2 つのスレッドを作成し、個別のスレッドで各ストリームの出力を読み取ることで、デッドロック状態を回避できます。