15

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);
    }
0

2 Answers 2

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))
    {
      ....    
    }
}
Sign up to request clarification or add additional context in comments.

12 Comments

Yes, and in addition you need to set RedirectStandardOutput to true for this to work.
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.
I also had to add myProc.BeginOutputReadLine(); after I had started the process.
@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."
@RToyo IsNullOrEmpty should not be used since a null indicates to not continue but processing should continue after an empty line.
|
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();

1 Comment

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).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.