如何获取System.Diagnostics.Process的输出?

mar*_*cgg 34 c# windows asp.net system.diagnostics

我像这样运行ffmpeg:

System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo = new System.Diagnostics.ProcessStartInfo(ffmpegPath, myParams);
p.Start();
p.WaitForExit();
Run Code Online (Sandbox Code Playgroud)

...但问题是带有ffmpeg的控制台会立即弹出并消失,所以我无法获得任何反馈.我甚至不知道该过程是否正确运行.

那么我怎么能:

  • 告诉控制台保持打开状态

  • 在C#中检索控制台显示的内容

Luc*_*nes 49

您需要做的是捕获标准输出流:

p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
// instead of p.WaitForExit(), do
string q = "";
while ( ! p.HasExited ) {
    q += p.StandardOutput.ReadToEnd();
}
Run Code Online (Sandbox Code Playgroud)

您可能还需要做类似的事情StandardError.然后,您可以按照自己的意愿行事q.

正如我在一个问题中发现的那样,这有点挑剔

正如Jon Skeet指出的那样,使用像这样的字符串连接并不是明智的表现.你应该使用StringBuilder:

p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
// instead of p.WaitForExit(), do
StringBuilder q = new StringBuilder();
while ( ! p.HasExited ) {
    q.Append(p.StandardOutput.ReadToEnd());
}
string r = q.ToString();
Run Code Online (Sandbox Code Playgroud)

  • 正确的基本内容,但我不建议像这样建立字符串.使用StringBuilder :) (5认同)
  • 使用此方法存在竞争条件:如果在进入while循环之前进程结束,则不会读取输出. (2认同)

chi*_*oro 19

Lucas的回答有一个竞争条件:如果进程快速结束,即使剩下一些输出,也会保留while循环(或从不进入),也就是说你可能错过了一些数据.为防止这种情况,ReadToEnd应在退出流程后再完成另一项工作.

(请注意,与我的答案的旧版本相比,我再也看不到需要WaitForExit一旦process.HasExited标志为真,所以这归结为:)

using (var process = Process.Start(startInfo))
{
    var standardOutput = new StringBuilder();

    // read chunk-wise while process is running.
    while (!process.HasExited)
    {
        standardOutput.Append(process.StandardOutput.ReadToEnd());
    }

    // make sure not to miss out on any remaindings.
    standardOutput.Append(process.StandardOutput.ReadToEnd());

    // ...
}
Run Code Online (Sandbox Code Playgroud)


Mic*_*uez 5

我知道这个问题已经很老了,但我还是会补充一下。

如果您只想显示命令行进程的输出,并且从控制台窗口生成该进程,则只需重定向标准输入(是的,我知道这听起来不对,但它有效)。

所以:

System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo = new System.Diagnostics.ProcessStartInfo(ffmpegPath, myParams);
p.UseShellExecute = false;
p.RedirectStandardInput = true;
p.Start();
p.WaitForExit();
Run Code Online (Sandbox Code Playgroud)

会做得很好。

  • 是我喝醉了,还是 Michael Vasquez 的名字以及他评论周围的大部分 HTML 都倒过来了? (19认同)
  • 这是因为在“不是”之后。有两个以utf-8编码的U+202E(从右到左覆盖)序列,即0xe2 0x80 0xae 0xe2 0x80 0xae。 (6认同)