1

Process クラスを使用してコンソール アプリケーションを生成する GUI アプリケーションがあります。

Process p1 = new Process();
p1.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p1.StartInfo.CreateNoWindow = true;
p1.StartInfo.UseShellExecute = false;
p1.StartInfo.FileName = Path.Combine(basepath, "abc.exe");
p1.StartInfo.Arguments = "/pn abc.exe /f \"temp1.txt\"";
p1.StartInfo.RedirectStandardError = true;
p1.StartInfo.RedirectStandardInput = true;
p1.StartInfo.RedirectStandardOutput = true;
p1.OutputDataReceived += new DataReceivedEventHandler(outputreceived);
p1.ErrorDataReceived += new DataReceivedEventHandler(errorreceived);
p1.Start();
tocmd = p1.StandardInput;
p1.BeginOutputReadLine();
p1.BeginErrorReadLine();

現在、コンソール出力を非同期に読み取りますが、内部バッファーがある程度満たされた場合にのみイベントを発生させるように見えるという問題があります。データをそのまま表示したい。バッファに 10 バイトある場合は、10 バイトを表示します。私のプログラムは sleep() 呼び出しを内部的に実装しているため、スリープ状態になるまでデータを出力する必要があります。

どうすればできますか?

=============

出力が行バッファリングされていると述べたように、コードで次の変更を試みました

p1.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p1.StartInfo.CreateNoWindow = true;
p1.StartInfo.UseShellExecute = false;
p1.StartInfo.FileName = Path.Combine(basepath, "abc.exe");
p1.StartInfo.Arguments = pnswitch + " /f \"temp1.txt\"";
p1.StartInfo.RedirectStandardError = false;
p1.StartInfo.RedirectStandardInput = true;
p1.StartInfo.RedirectStandardOutput = true;
p1.Start();
tocmd = p1.StandardInput;
MethodInvoker mi = new MethodInvoker(readout);
mi.BeginInvoke(null, p1);

そして私が書いた内部の読み出し

void readout()
    {
        string str;
        while ((str = p1.StandardOutput.ReadLine()) != null)
        {
            richTextBox1.Invoke(new UpdateOutputCallback(this.updateoutput), new object[] { str });
            p1.StandardOutput.BaseStream.Flush();
        }
    }

それで、各行がいつ書き込まれるかを監視し、正しく印刷すると思いますか?これもうまくいきませんでした。何か問題がありますか?

4

2 に答える 2

3

受信した出力データとエラー データはライン バッファリングされ、改行が追加された場合にのみ発生します。

あなたの最善の策は、入力をバイト単位で読み取ることができる独自のリーダーを使用することです。明らかに、これはノンブロッキングでなければなりません:)

于 2009-03-09T11:25:08.600 に答える
1

これを実現するには、リダイレクトされたストリームで同期読み取り操作を使用する必要があります。コードは次のようになります (MSDN サンプル):

// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "Write500Lines.exe";
p.Start();
// Do not wait for the child process to exit before
// reading to the end of its redirected stream.
// p.WaitForExit();
// Read the output stream first and then wait.
**string output = p.StandardOutput.ReadToEnd();**
p.WaitForExit();

非同期動作を実現するには、いくつかのスレッドを使用する必要があります。

MSDNの記事はこちら

于 2009-03-09T11:44:14.480 に答える