C# 在读取异步时等待 shell 命令返回

标签 c# asynchronous

我需要从 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/

相关文章:

c# - Autofac 将参数传递给嵌套类型

C# Excel RTD 服务器多实例断开一张纸上的所有公式停止另一张纸上的公式

c# - 使用反射来获取对象属性的属性

javascript - 当异步递归方法完全准备好时如何创建回调

C# 跨多个监视器控制菜单位置

c# - 在 AxWindowsMediaPlayer 上叠加 Picturebox(或图像)

python - 使用 Twisted 同时记录和获取命令行输入

python - 如何将 "merge"两个Python扭曲应用程序?

c# - C# await 关键字是否会导致函数调用阻塞?

python - 异步函数中的 PyMySql 查询