我正在尝试执行命令行程序并将其输出实时打印到文本框中:
private void btnExecute_Click(object sender, EventArgs e)
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.CreateNoWindow = true;
startInfo.FileName = Application.StartupPath + "\\Deps\\ats.exe";
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
using (Process exeProcess = Process.Start(startInfo))
{
exeProcess.OutputDataReceived += exeProcess_OutputDataReceived;
exeProcess.BeginOutputReadLine();
//MessageBox.Show("Hello"); //Notice this message box before calling WaitForExit
exeProcess.WaitForExit(45000);
}
private void exeProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (txtOutput.InvokeRequired)
{
txtOutput.Invoke(new MethodInvoker(delegate { txtOutput.Text += Environment.NewLine + e.Data; }));
}
}
}
代码运行时没有错误,但不会向txtOutput打印任何内容 但是,如果我取消注释消息框,则会显示MessageBox并实时更新txtOutput 现在,如果我点击“确定”'关闭MessageBox,txtOutput再次停止更新!!
这到底发生了什么?为什么textBox只在我显示MessageBox时更新?
答案 0 :(得分:0)
好的,所以你在这里遇到的问题可能是exeProcess.WaitForExit(45000);
阻止了UI线程。因此,对txtOutput.Invoke
的调用将消息发布到窗口消息队列,该队列由UI线程处理。由于该UI线程被等待状态阻止,因此无法处理这些文本框帖子。
所以你需要做的是等待进程退出而不阻塞UI线程。有几种方法可以做到这一点,但一种方法是使用进程Exited
事件回调。我没有在这里看到足够的代码来给出一个完整的例子,但你想重写这样的东西:
private Process _exeProcess;
private void btnExecute_Click(object sender, EventArgs e)
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.CreateNoWindow = true;
startInfo.FileName = Application.StartupPath + "\\Deps\\ats.exe";
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
_exeProcess = Process.Start(startInfo);
_exeProcess.OutputDataReceived += exeProcess_OutputDataReceived;
_exeProcess.BeginOutputReadLine();
_exeProcess.Exited += ContinueOnYourWay;
}
private void ContinueOnYourWay(object sender, EventArgs e)
{
// Clean up
_exeProcess.Dispose();
_exeProcess = null;
// More code here
}
private void exeProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (txtOutput.InvokeRequired)
{
txtOutput.Invoke(new MethodInvoker(delegate { txtOutput.Text += Environment.NewLine + e.Data; }));
}
}