我已经实现了以下代码(改编自tutorial),以便运行命令提示符窗口,运行程序并读取输出。从ButtonClick事件处理程序调用代码,该处理程序嵌套在用户控件中。
我的印象是,由于这些方法是“异步的”,这将允许我的程序的其余部分在外部进程运行时运行。但是,这似乎并非如此,因为我的UI将在操作运行时冻结。我应该补充一点,当cmd进程结束时收到的输出是正确的。
很抱歉转储这样的代码,只是不确定此时还要做什么!
非常感谢任何协助。
public static void runExternalProcess()
{
StringBuilder output = new StringBuilder();
Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.UseShellExecute = false;
cmd.StartInfo.CreateNoWindow = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.OutputDataReceived += new DataReceivedEventHandler(outputEventHandler);
cmd.StartInfo.RedirectStandardInput = true;
cmd.Start();
cmd.BeginOutputReadLine();
StreamWriter sortStreamWriter = cmd.StandardInput;
StreamWriter sw = cmd.StandardInput;
if (sw.BaseStream.CanWrite)
{
sw.WriteLine("ping www.google.com");
}
sw.Close();
cmd.WaitForExit();
MessageBox.Show(output.ToString());
cmd.Close();
}
private static void outputEventHandler(object sendingProcess, DataReceivedEventArgs e)
{
if (!String.IsNullOrEmpty(e.Data))
{
output.Append(e.Data + Environment.NewLine);
}
}
答案 0 :(得分:4)
你的问题在这里:
cmd.WaitForExit();
这是阻止通话。
如果您想在不阻止的情况下响应退出流程,则需要为Exited事件添加处理程序。
答案 1 :(得分:4)
如何注册Exited
事件并在那里显示MessageBox
:
StringBuilder output = new StringBuilder();
Process cmd = new Process();
public void RunExternalPing()
{
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.UseShellExecute = false;
cmd.StartInfo.CreateNoWindow = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.RedirectStandardInput = true;
cmd.EnableRaisingEvents = true;
cmd.OutputDataReceived +=
new DataReceivedEventHandler(cmd_OutputDataReceived);
cmd.Exited += new EventHandler(cmd_Exited);
cmd.Start();
cmd.BeginOutputReadLine();
StreamWriter sw = cmd.StandardInput;
sw.WriteLine("ping www.google.com");
sw.Close();
}
void cmd_Exited(object sender, EventArgs e)
{
MessageBox.Show(output.ToString());
cmd.Dispose();
}
private void cmd_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (!String.IsNullOrEmpty(e.Data))
{
output.Append(e.Data + Environment.NewLine);
}
}
来自MSDN:
关联过程有两种方式得到通知 退出:同步和异步。同步通知 依赖于调用WaitForExit方法来暂停处理 您的应用程序,直到相关组件退出。异步 通知依赖于退出事件。在任一情况下, 对于Process组件,必须将EnableRaisingEvents设置为true 收到流程已退出的通知。
答案 2 :(得分:2)
所有这些代码都是线性的,如果你不想冻结你所在的线程,你应该创建一个新线程并在该线程完成时执行回调。