2009-03-09 10 views
1

私はProcessクラスを使用してコンソールアプリケーションを作成しているGUIアプリケーションを持っています。C#アプリケーションから作成された別のプロセスの標準出力を部分的に読み取る

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()コールを内部的に実装しているので、スリープ状態になるまでデータを出力する必要があります。

どうすればいいですか?それは出力ラインバッファリングされている述べたよう

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

、iはコード

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); 

及び読み出しI内部で以下の変更をしようとしました書いた

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

だから私は今、それはそれぞれの行が書かれ、それを正しく印刷すると思いますか?これも機能しませんでした。そこに何か間違っている?

答えて

3

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

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

+0

私は私自身のリーダーを作って行くことができる方法として任意のアイデア?私はいくつかのデータを持っているたびにstdoutputストリームを監視し、そこから読み込むいくつかの関数を書くことができませんか? –

+0

はい、そうです。別のスレッドからStandardOutputを読み込みます。 – leppie

+0

私はコードを変更して、それを行ごとに読むようにしました。あなたは一見を持つことができますか? –

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の記事here

+0

私はそれに非同期呼び出しを行いました。あなたは更新された質問とそのコメントを見ていただけますか? –

関連する問題