20

プロセスの出力をそのままコンソールに表示したい (標準出力と標準エラーが 1 つのストリームに混在している)。それを行う方法はありますか?

使おうと思ってた

ProcessStartInfo.UseShellExecute = true;  

しかし、出力を非同期に読み取ることはできません。私が設定した場合

process.ProcessStartInfo.UseShellExecute = false;  
process.StartInfo.RedirectStandardOutput = true;
process.OutputDataReceived += new DataReceivedEventHandler(partialOutputHandler);

次に、標準出力を読み取ることができます (標準エラーについても同じことができます) が、コンソールの動作 (stdout と stderr の混合) をシミュレートする方法がわかりません。

これは、標準エラー ストリームを標準出力ストリームにリダイレクトする機能を持つ Linux に似ています。どうやって?

4

4 に答える 4

47

このようなことを意味しますか?

SynchronizationContext _syncContext;
MyForm()
{
    _syncContext = SynchronizationContext.Current;
}

void StartProcess()
{
    using (var process = new Process
        {
            StartInfo = new ProcessStartInfo
            {
                FileName = "myProcess.exe",
                UseShellExecute = false,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
            }
        })
    {
        process.OutputDataReceived += (sender, args) => Display(args.Data);
        process.ErrorDataReceived += (sender, args) => Display(args.Data);

        process.Start();
        process.BeginOutputReadLine();
        process.BeginErrorReadLine();

        process.WaitForExit(); //you need this in order to flush the output buffer
    }   
}

void Display(string output)
{
    _syncContext.Post(_ => myTextBox.AppendText(output), null);
}
于 2012-09-24T18:34:31.393 に答える
3

MSDNの記事には次のように記載されています。

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

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

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

同じことがに当てはまるStandardOutputので、両方のストリームを非同期で読み取るだけです。

Merging両方のストリームが1つになり、エラー報告と「製品」情報の検出が複雑になります。

于 2012-09-24T13:46:53.590 に答える