C# get process output while running
Asked Answered
F

2

14

Is there anyway to redirect standard output of a spawned process and capture it as its happening. Everything I have seen just does a ReadToEnd after the process has finished. I would like to be able to get the output as it is being printed.

Edit:

    private void ConvertToMPEG()
    {
        // Start the child process.
        Process p = new Process();
        // Redirect the output stream of the child process.
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.RedirectStandardOutput = true;
        //Setup filename and arguments
        p.StartInfo.Arguments = String.Format("-y -i \"{0}\" -target ntsc-dvd -sameq -s 720x480 \"{1}\"", tempDir + "out.avi", tempDir + "out.mpg");
        p.StartInfo.FileName = "ffmpeg.exe";
        //Handle data received
        p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
        p.Start();
    }

    void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        Debug.WriteLine(e.Data);
    }
Fredelia answered 16/8, 2012 at 20:0 Comment(0)
T
19

Use Process.OutputDataReceived event from the process, to recieve the data you need.

Example:

var myProc= new Process();

...            
myProc.StartInfo.RedirectStandardOutput = true;
myProc.OutputDataReceived += new DataReceivedEventHandler(MyProcOutputHandler);

...

private static void MyProcOutputHandler(object sendingProcess, 
            DataReceivedEventArgs outLine)
{
            // Collect the sort command output. 
    if (!String.IsNullOrEmpty(outLine.Data))
    {
      ....    
    }
}
Tantalite answered 16/8, 2012 at 20:4 Comment(12)
Yes, and in addition you need to set RedirectStandardOutput to true for this to work.Winne
@vcsjones: just wrinting additional post.Tantalite
I tried that but I'm not having any luck. It runs fine but the callback is never hit. Maybe its a problem with the way the output is being printed. I am using this with ffmpeg. I will add my code to the original post.Fredelia
@thecaptain0220: but if you use ReadToEnd(..) does it work for you?Tantalite
No I tried p.WaitForExit() followed by p.ReadToEnd() and it returns an empty stringFredelia
@thecaptain0220: are you sure, at this point, that the process write something to output?Tantalite
If I set RedirectStandardOutput to false I can see all the status messages for the converting process.Fredelia
I also had to add myProc.BeginOutputReadLine(); after I had started the process.Toronto
What is if (!String.IsNullOrEmpty(outLine.Data)) for? Can data ever be null? Don't you want the empty lines in the output most of the time?Sickening
@Lii: question is about filtering out the commands or some keywords from the stream, which are nor 'null' or empty strings, I guess.Tantalite
@lii The dataReceivedEventHandler documentation says: "When the redirected stream is closed, a null line is sent to the event handler. Ensure that your event handler checks for this condition before accessing the Data property. For example, you can use the static method String.IsNullOrEmpty to validate the Data property in your event handler."Tussle
@Tussle IsNullOrEmpty should not be used since a null indicates to not continue but processing should continue after an empty line.Kenrick
F
9

So after a little more digging I found out that ffmpeg uses stderr for output. Here is my modified code to get the output.

        Process p = new Process();

        p.StartInfo.UseShellExecute = false;

        p.StartInfo.RedirectStandardOutput = true;
        p.StartInfo.RedirectStandardError = true;

        p.StartInfo.Arguments = String.Format("-y -i \"{0}\" -target ntsc-dvd -sameq -s 720x480 \"{1}\"", tempDir + "out.avi", tempDir + "out.mpg");
        p.StartInfo.FileName = "ffmpeg.exe";

        p.ErrorDataReceived += new DataReceivedEventHandler(p_ErrorDataReceived);
        p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);

        p.Start();

        p.BeginErrorReadLine();
        p.WaitForExit();
Fredelia answered 16/8, 2012 at 21:0 Comment(1)
Great example! unfortunately does not work with p.StartInfo.UseShellExecute = true; (say, when trying to capture a long-running msbuild process and displaying the output in realtime in the Visual Studio output window).Neutralization

© 2022 - 2024 — McMap. All rights reserved.