部分读取从c#应用程序创建的另一个进程的标准输出

时间:2009-03-09 11:19:01

标签: c# process redirect standards

我有一个GUI应用程序,我在其中使用Process类生成一个控制台应用程序。

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

所以我认为它现在可以监控每行的写入时间并打印出来吗?这也行不通。那有什么不对吗?

2 个答案:

答案 0 :(得分:3)

接收的输出和错误数据是行缓冲的,只有在添加换行符时才会触发。

您最好的选择是使用您自己的读取器,可以逐字节读取输入。显然,这必须是非阻塞的:)

答案 1 :(得分: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