【问题标题】:Reading error output hangs for command invoked on CMD process在 CMD 进程上调用的命令读取错误输出挂起
【发布时间】:2014-01-01 04:23:12
【问题描述】:

我有用于 ffmpeg 命令调用的 c# 控制台应用程序。在这里

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

如果我删除这行代码

string errors = console.StandardError.ReadToEnd();

这个程序可以正常工作。否则它会挂起。我需要错误信息,如果有的话,怎么办,请帮忙。

【问题讨论】:

    标签: c# process cmd stderr system.diagnostics


    【解决方案1】:

    问题原因

    您的程序挂起是因为

    • cmd 是一个交互式命令行应用程序,因此 不断std 生成输出。出std。错误
    • Process.StandardError.ReadToEnd() 读取 std 的输出。一个进程的错误流直到它到达流的末尾

    因为 cmd 是一个交互式命令行应用程序 - 它不会结束它的 std。错误 流直到 cmd 进程终止 - 这就是为什么 Process.StandardError.ReadToEnd() 在运行 cmd 进程时被调用时挂起。

    问题的解决方案

    要为您执行的每个命令获取输出,至少有以下两个选项:

    1. 使用单独的 Process 实例启动每个命令 - 并使用 StreamReader 类的标准方法(ReadToEnd()Read() 方法)读取输出。
    2. cmd 应用程序使用单个 Process 实例 - 以交互方式对其进行读写:

      • 启动流程如下例:

        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();
        
      • 使用以下代码向 cmd 写入命令

        interactiveProcess.StandardInput.WriteLine(command);
        
      • 要读取响应,您需要使用System.Threading.Thread.Sleep() 方法并等待processOutput 变量在执行启动命令期间填充输出。

    【讨论】:

    • 您好,我根据您的建议编辑了我的代码。它表现更好。但是没有收到所有的 ffmpeg 错误消息。我在 C:\users\vishnu.aravind 中安装了我的 ffmpeg.exe。假设如果我从 C:\ 运行 ffmpeg,它只会将错误消息显示为“FFmpeg 未被识别为命令”。此错误消息是一个很好的错误消息。但是,如果我在发布到 Alarm04.wav 的代码中编辑 Alarm03.wav(在文件夹中不可用),它必须显示一些错误消息。但不幸的是它没有显示。
    • @user1665130 我发现 2 个潜在问题可能会阻止您收到错误消息。 首先: 您的 ffmpeg 命令可能未使用您的代码正确启动 - 要启动它,您不能将其可执行文件放在 C: 驱动器的根目录中,只需指定完整路径当你在代码中调用它时命令的文件。 第二个:错误文本可能通过标准输出流而不是ffmpeg命令通过错误输出流路由。
    【解决方案2】:

    在读取错误之前尝试等待退出:

    cmd.WaitForExit();
    

    【讨论】:

    • cmd.WaitForExit 不可用。我试过 console.WaitForExit();没用。
    猜你喜欢
    • 2016-02-24
    • 1970-01-01
    • 1970-01-01
    • 2011-10-17
    • 1970-01-01
    • 2015-07-29
    • 2012-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多