简体   繁体   English

从Process.Start()获得所需输出的问题

[英]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. 现在我正在尝试使用Comskip从我的有线卡调谐器中识别视频录制中的商业广告。 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 我期待stdout能够抓住屏幕上显示的内容,就像手动启动应用程序时一样(下面的屏幕截图),这是应用程序正在进行的连续馈送,并且输出中混合的是给出%的行进度,我想用它来更新进度条

命令行输出

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" 使用的命令行是:“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. 根据命令行将ini文件设置为C:\\ Users \\ Chris \\ Desktop \\ ComSkip Tuning Files \\ comskip_ModernFamily.ini使用C:\\ Users \\ Chris \\ Desktop \\ ComSkip Tuning Files \\ comskip_ModernFamily.ini获取初始值。

I also tried redirecting the StandardError stream and grabbing process.StandardError.ReadToEnd(); 我还尝试重定向StandardError流并抓取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? 我错过了什么来捕捉我希望的东西,或者这个应用程序的输出流是否可能在其他无法访问的地方?

See the docs on RedirectStandardOutput . 请参阅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. 您应该使用事件OutputDataReceived并可能使用ErrorDataReceived并更新处理程序中的进度条。

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 并在ReadOutputErrorOutput捕获输出

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM