Problems getting desired output from Process.Start

2019-02-28 03:17发布

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?

2条回答
We Are One
2楼-- · 2019-02-28 03:38

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;
     }
  }
查看更多
Ridiculous、
3楼-- · 2019-02-28 03:50

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.

查看更多
登录 后发表回答