我需要从C#应用程序运行外部进程,但在继续执行之前等待它返回 . 同时,我需要从stdout获取并更新包含进度信息的文本框 . 由于命令可能会运行几分钟并在此期间打印信息,因此显示绝对必要;但是可能会运行多个命令并且必须按顺序排列,因此等待也是如此 .
我试图使用:
p = Process.Start();
p.BeginOutputReadLine();
p.WaitForExit();
但是在等待时冻结了UI线程并阻止了输出的出现 . 这个:
p.Start();
p.BeginOutputReadLine();
while (!p.HasExited)
{
Application.DoEvents();
Thread.Sleep(100);
}
效果更好,但是完全错误/坏主意并且实际上并没有等待整个期间 .
我还简要地尝试使用BackgroundWorker来启动shell进程,但是我不确定如何让UI线程在没有阻塞的情况下等待工作者完成 .
我想要做的是提供类似于 ShowDialog()
的 DialogResult ShellExecute(String cmd)
,它返回OK / Cancel(/ fail)结果,如果用户允许命令完成,单击取消,或者命令's return code. It shouldn' t返回,直到命令完成(或者取消) .
所有shell命令都运行于:
ProcessStartInfo info = new ProcessStartInfo
{
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
FileName = "cmd.exe",
Arguments = "/c " + command
};
重定向输出并有效地执行命令 .
我将如何正确地创建一个启动异步进程的函数,但仍然等待直到完成返回?
2 回答
从ProcessStartInfo创建您的流程,
澄清:ProcessStartinfo si需要类似的东西
然后呢
使用
同
重写了大部分代码以使其正常工作 .
ProgressForm
类提供QueueCommand
方法,获取所需的shell命令和前/后委托 . 显示时,进度表单使用后台工作程序执行每个命令,处理返回代码并在适当时执行下一个命令 .后台工作程序等待每个shell命令完成(
Process.WaitForExit()
),同时异步提供UI线程输出 . 完成后,它会调用一个启用成功/确定按钮并隐藏进度条的方法 .