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

时间:2009-09-07 18:45:40

标签: c# asp.net windows system.diagnostics

我像这样运行ffmpeg:

System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo = new System.Diagnostics.ProcessStartInfo(ffmpegPath, myParams);
p.Start();
p.WaitForExit();

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

那么我怎么能:

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

  • 在C#中检索控制台是什么 显示

4 个答案:

答案 0 :(得分:49)

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

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

您可能还需要执行与StandardError类似的操作。然后,您可以使用q执行所需操作。

有点挑剔,正如我在one of my questions

中发现的那样

正如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();

答案 1 :(得分: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());

    // ...
}

答案 2 :(得分:4)

对于与ffmpeg直接相关的更具体的答案,将“-report”命令传递给ffmpeg将使其将日志转储到当前目录中,并显示该过程的显示内容。

  

' - 报告'

     

将完整的命令行和控制台输出转储到名为的文件   当前目录中的program-YYYYMMDD-HHMMSS.log。这个文件可以   对bug报告很有用。它还暗示了-loglevel verbose。

     

注意:将环境变量FFREPORT设置为任何值都具有   同样的效果。

来自FFMpeg Documentation

答案 3 :(得分:3)

我知道这个问题已经过时了,但无论如何我都会加入它。

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

所以:

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();

会没事的。