How to get the output of a System.Diagnostics.Process?

浪尽此生 提交于 2019-11-26 13:48:57

问题


I run ffmpeg like this:

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

... but the problem is that the console with ffmpeg pops up and disappears right away, so I can't get any feedback. I don't even know if the process ran correctly.

So how can I either:

  • Tell the console to stay opened

  • Retrieve in the C# what the console displayed


回答1:


What you need to do is capture the Standard Output stream:

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

You may also need to do something similar with StandardError. You can then do what you wish with q.

It is a bit finicky, as I discovered in one of my questions

As Jon Skeet has pointed out, it is not smart performance-wise to use string concatenation like this; you should instead use a 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();



回答2:


Lucas' answer has a race condition: If the process finishes quickly the while loop is left (or never entered) even if there is some output left, that is you might miss out on some data. To prevent that, another ReadToEnd should be done after the process exited.

(Note that in comparison to the old version of my answer, I can no longer see a need for WaitForExit once the process.HasExited flag is true, so this boils down to:)

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

    // ...
}



回答3:


For a more specific answer directly related to ffmpeg, passing the "-report" command into ffmpeg will make it dump a log into the current directory with what was said in the display of the process.

‘-report’

Dump full command line and console output to a file named program-YYYYMMDD-HHMMSS.log in the current directory. This file can be useful for bug reports. It also implies -loglevel verbose.

Note: setting the environment variable FFREPORT to any value has the same effect.

From FFMpeg Documentation.




回答4:


I know this question is old, but I'll add to it anyway.

If all you wish to do is display the output of a command line process, and you're spawning the process from a console window, you need only redirect the standard input (yes, I know it sounds wrong, but it works).

So:

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

Would do just fine.



来源:https://stackoverflow.com/questions/1390559/how-to-get-the-output-of-a-system-diagnostics-process

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!