psubsee2003
psubsee2003

Reputation: 8741

Problems getting desired output from Process.Start()

I am working on an application that calls several command line applications to do some post processing on some video files.

Right now I am trying to use Comskip to identify the commercial breaks in a video recording from my cable card tuner. This runs just fine, but I am having problems getting the screen output that I need.

String stdout = null;

using (var process = new Process())
{
    var start = new ProcessStartInfo(comskip, cmdLine);

    start.WindowStyle = ProcessWindowStyle.Normal;
    start.CreateNoWindow = true;
    start.UseShellExecute = false;
    start.RedirectStandardOutput = true;

    process.StartInfo = start;

    process.Start();
    process.WaitForExit();

    stdout = process.StandardOutput.ReadToEnd();
}

I'm expecting stdout to grab what is displayed on the screen the same as when the application is launched manually (screen shot below) which is a continuous feed of what the application is doing, and mixed in the output are lines that give a % progress, which I want to use to update a progress bar

output from commandline

But running the above code only gives me:

The commandline used was: "C:\Users\Chris\Google Drive\Tools\ComSkip\comskip.exe" "C:\Users\Chris\Desktop\ComSkip Tuning Files\Modern Family.wtv" "--ini=C:\Users\Chris\Desktop\ComSkip Tuning Files\comskip_ModernFamily.ini"

Setting ini file to C:\Users\Chris\Desktop\ComSkip Tuning Files\comskip_ModernFamily.ini as per commandline Using C:\Users\Chris\Desktop\ComSkip Tuning Files\comskip_ModernFamily.ini for initiation values.

I also tried redirecting the StandardError stream and grabbing process.StandardError.ReadToEnd(); but the process appears to hang if I run with these options.

Am I missing something to capture what I'm hoping for, or is it possible that the output stream for this application is going somewhere else that is not accessible?

Upvotes: 1

Views: 2951

Answers (2)

Mike Zboray
Mike Zboray

Reputation: 40798

See the docs on RedirectStandardOutput. Waiting for the child process to end before reading the output can cause a hang.

It particular, the example says not to do what you have done:

 Process p = new Process();
 // Redirect the output stream of the child process.
 p.StartInfo.UseShellExecute = false;
 p.StartInfo.RedirectStandardOutput = true;
 p.StartInfo.FileName = "Write500Lines.exe";
 p.Start();
 // Do not wait for the child process to exit before
 // reading to the end of its redirected stream.
 // p.WaitForExit();
 // Read the output stream first and then wait.
 string output = p.StandardOutput.ReadToEnd();
 p.WaitForExit();

You should use the events OutputDataReceived and possibly ErrorDataReceived and update the progress bar in the handler.

Upvotes: 2

VladL
VladL

Reputation: 13033

You must set following:

     process.StartInfo.RedirectStandardOutput = true;
     process.StartInfo.RedirectStandardError = true;
     process.StartInfo.UseShellExecute = false;
     process.OutputDataReceived += new DataReceivedEventHandler(ReadOutput);
     process.ErrorDataReceived += new DataReceivedEventHandler(ErrorOutput);

     process.Start();
     process.BeginOutputReadLine();
     process.BeginErrorReadLine();
     process.WaitForExit();

and catch the output in ReadOutput and ErrorOutput

  private static void ErrorOutput(object sender, DataReceivedEventArgs e)
  {
     if (e.Data != null)
     {
        stdout = "Error: " + e.Data;
     }
  }

  private static void ReadOutput(object sender, DataReceivedEventArgs e)
  {
     if (e.Data != null)
     {
        stdout = e.Data;
     }
  }

Upvotes: 2

Related Questions