1

我有一个 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();
        }
    }

所以我认为它现在监控每一行何时被写入并打印它对吗?这也没有用。那里有什么问题吗?

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 回答