如何将进程输出(控制台)重定向到richtextbox?

有什么问题,为什么richtextbox没有获得Process输出流? 在richtextbox中没有文本显示..

private void button1_Click(object sender, EventArgs e) { Process sortProcess; sortProcess = new Process(); sortProcess.StartInfo.FileName = "sort.exe"; sortProcess.StartInfo.Arguments = this.comboBox1.SelectedItem.ToString(); // Set UseShellExecute to false for redirection. sortProcess.StartInfo.CreateNoWindow = true; sortProcess.StartInfo.UseShellExecute = false; // Redirect the standard output of the sort command. // This stream is read asynchronously using an event handler. sortProcess.StartInfo.RedirectStandardOutput = true; sortOutput = new StringBuilder(""); // Set our event handler to asynchronously read the sort output. sortProcess.OutputDataReceived += new DataReceivedEventHandler(SortOutputHandler); // Redirect standard input as well. This stream // is used synchronously. sortProcess.StartInfo.RedirectStandardInput = true; // Start the process. sortProcess.Start(); // Start the asynchronous read of the sort output stream. sortProcess.BeginOutputReadLine(); sortProcess.WaitForExit(); richTextBox1.AppendText(sortOutput.ToString()); } private static void SortOutputHandler(object sendingProcess, DataReceivedEventArgs outLine) { sortOutput.Append(Environment.NewLine + "[" + numOutputLines.ToString() + "] - " + outLine.Data); } } 

所以当sort.exe启动时,它显示文本,我希望所有这些文本也显示在RealTime的richtextbox中(我不想等待进程退出,然后读取所有输出)

我该怎么做? 我的代码中有任何错误的部分? 谢谢

更新@botz

我在我的代码中添加了这个

  private void SortOutputHandler(object sendingProcess, DataReceivedEventArgs outLine) { sortOutput.Append(Environment.NewLine + "[" + numOutputLines.ToString() + "] - " + outLine.Data); richTextBox1.AppendText(sortOutput.ToString()); } 

但它抛出了这个例外

 Cross-thread operation not valid: Control 'richTextBox1' accessed from a thread other than the thread it was created on. 

WaitForExit()会阻止您的UI线程,因此您看不到新的输出。 要么在单独的线程中等待进程,要么用这样的东西替换WaitForExit()

 while (!sortProcess.HasExited) { Application.DoEvents(); // This keeps your form responsive by processing events } 

SortOutputHandler ,您现在可以直接将输出附加到文本框中。 但是你应该记得检查是否需要在UI线程上调用它。

您可以在处理程序中以这种方式检查它是否在UI线程中:

  if (richTextBox1.InvokeRequired) { richTextBox1.BeginInvoke(new DataReceivedEventHandler(SortOutputHandler), new[] { sendingProcess, outLine }); } else { sortOutput.Append(Environment.NewLine + "[" + numOutputLines.ToString() + "] - " + outLine.Data); richTextBox1.AppendText(sortOutput.ToString()); } 

这对我有用:

 private void button1_Click(object sender, EventArgs e) { using (Process sortProcess = new Process()) { sortProcess.StartInfo.FileName = @"F:\echo_hello.bat"; sortProcess.StartInfo.CreateNoWindow = true; sortProcess.StartInfo.UseShellExecute = false; sortProcess.StartInfo.RedirectStandardOutput = true; // Set event handler sortProcess.OutputDataReceived += new DataReceivedEventHandler(SortOutputHandler); // Start the process. sortProcess.Start(); // Start the asynchronous read sortProcess.BeginOutputReadLine(); sortProcess.WaitForExit(); } } void SortOutputHandler(object sender, DataReceivedEventArgs e) { Trace.WriteLine(e.Data); this.BeginInvoke(new MethodInvoker(() => { richTextBox1.AppendText(e.Data ?? string.Empty); })); } 

您开始使用的示例是一个控制台应用程序,它不关心multithreading访问。 对于Windows窗体,当您更新控件时,必须从主UI线程完成,这就是需要BeginInvoke原因。 如果要快速检查SortOutputHandler类的处理程序是否正常工作,可以使用System.Diagnostics.Trace.Write* ,它不需要BeginInvoke

编辑: echo_hello.bat简单地回应“你好”字符串:

 @echo off echo hello 

如果要从另一个线程更新ui,则需要确保您在主ui线程上。 在方法中检查InvokeRequired。 请参见InvokeRequired

完整的应用程序和源代码可从codeproject的外部链接获得:

http://www.codeproject.com/Articles/335909/Embedding-a-Console-in-aC-Application

这是https://github.com/dwmkerr/consolecontrol的实现教程。