我需要从 C# 应用程序运行外部进程,但要等待它返回才能继续执行。同时,我需要获取并更新带有来自标准输出的进度信息的文本框。由于该命令可能会运行几分钟并在此期间打印信息,因此显示该信息是绝对必要的;但可能会运行多个命令并且必须按顺序运行,因此等待也是如此。
我尝试使用:
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) 结果,如果用户允许命令完成、单击“取消”或命令的返回代码。在命令完成(或取消)之前它不应返回。
所有 shell 命令都运行:
ProcessStartInfo info = new ProcessStartInfo
{
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
FileName = "cmd.exe",
Arguments = "/c " + command
};
重定向输出并有效地通过 shell 执行命令。
我将如何正确创建一个启动异步进程的函数,但仍然等到该进程完成才返回?
最佳答案
从 ProcessStartInfo 创建流程,
澄清:ProcessStartinfo si 需要类似的内容
si.CreateNoWindow=true;
si.RedirectStandardOutput=true;
si.RedirectStandardError=true;
si.StandardOutputEncoding=Encoding.UTF8;
si.StandardErrorEncoding=Encoding.UTF8;
si.WindowStyle=ProcessWindowStyle.Hidden;
然后之前
p.Start();
使用
p.OutoutDataReceived+=OutputHandler;
与
private static void OutputHandler(object theProcess, DataReceivedEventArgs evtdata)
{
//evtdata.Data has the output data
//use it, display it, or discard it
}
关于C# 在读取异步时等待 shell 命令返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8593684/