Reading error output hangs for command invoked on CMD process

吃可爱长大的小学妹 提交于 2019-12-13 08:11:26

问题


I have c# console app for ffmpeg command invocation. Here is it

class Program
{
    static void Main(string[] args)
    {
        ProcessStartInfo cmd = new ProcessStartInfo("cmd.exe");

        cmd.RedirectStandardInput = true;
        cmd.RedirectStandardOutput = true;
        cmd.RedirectStandardError = true;
        cmd.UseShellExecute = false;
        cmd.CreateNoWindow = true;
        cmd.WindowStyle = ProcessWindowStyle.Hidden;
        Process console = Process.Start(cmd);

        console.StandardInput.WriteLine(@"cd C:\Users\vishnu.aravind");                     
        console.StandardInput.WriteLine(@"ffmpeg -i sunp.avi -i Alarm03.wav  -c:v copy -c:a aac -strict experimental output.avi");     

        string errors = console.StandardError.ReadToEnd();

        Console.WriteLine("Video file is created.");
        Console.Read();
    }
}

if I remove the line of code

string errors = console.StandardError.ReadToEnd();

this program will work fine. Else it hangs. I need the error information if any, what to do, please help.


回答1:


Cause of a problem

Your program hangs because

  • cmd is an interactive command line application and thus continually produces output for std. out and std. error stream
  • Process.StandardError.ReadToEnd() reads the output of std. error stream of a process till it reaches end of stream

as cmd is an interactive command line application - it will not end it's std. error stream until process of cmd terminates - and that's why Process.StandardError.ReadToEnd() hangs when it is invoked on running cmd process.

Solution for a problem

To get output for each command you execute there are at least two following options:

  1. Start each command with separate Process instance - and read output with standard methods of StreamReader class (ReadToEnd() and Read() methods).
  2. Use single Process instance for cmd application - to read and write to it interactively:

    • Start process as in following example:

      Process interactiveProcess = new Process();
      string processOutput = "";
      
      interactiveProcess.StartInfo.FileName = this.processPath;
      interactiveProcess.StartInfo.Arguments = commandLineParameters;
      interactiveProcess.StartInfo.UseShellExecute = false;
      interactiveProcess.StartInfo.CreateNoWindow = false;
      interactiveProcess.StartInfo.RedirectStandardInput = true;
      interactiveProcess.StartInfo.RedirectStandardError = true;
      interactiveProcess.Start();
      
      interactiveProcess.EnableRaisingEvents = true;
      
      interactiveProcess.ErrorDataReceived += new DataReceivedEventHandler((process, outputEventArgs) => processOutput += outputEventArgs.Data);
      
      interactiveProcess.BeginErrorReadLine();
      
    • Write commands to cmd with following code

      interactiveProcess.StandardInput.WriteLine(command);
      
    • To read response you will need to use System.Threading.Thread.Sleep() method and wait till processOutput variable is populated with output during execution of started commands.




回答2:


Try to wait for exit before reading errors:

cmd.WaitForExit();


来源:https://stackoverflow.com/questions/20565840/reading-error-output-hangs-for-command-invoked-on-cmd-process

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!