【问题标题】:Can't get output from cmd无法从 cmd 获取输出
【发布时间】:2014-03-13 08:02:50
【问题描述】:

我正在运行这个

        string path = string.Format(@"\\{0}\c$\Windows\CCM\Logs", computerName);

        Process process = Process.Start(new ProcessStartInfo()
        {
            FileName = "cmd.exe",
            Arguments = string.Format(@"net use {0} && dir {0}", path),
            UseShellExecute = false,
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            CreateNoWindow = true
        });

        string result = process.StandardOutput.ReadToEnd() + " " + process.StandardError.ReadToEnd();
        process.WaitForExit();

        Console.WriteLine(result);

但是没有任何东西被写入控制台。我究竟做错了什么?我可能已经浏览了有关此问题的所有其他 SO 线程,并进行了大量的谷歌搜索,但我无法让它工作。

【问题讨论】:

  • cmd.exe 在处理命令后不会自动关闭,它会等待进一步的输入,因此您的程序会在process.WaitForExit 停止,而不是转到Console.WriteLine(result)。基于事件侦听或异步输出的建议解决方案应该可以工作。

标签: c# process cmd output stdout


【解决方案1】:

你需要使用/C选项到cmd.exe否则子进程不会退出。

/C 执行字符串指定的命令,然后终止

(在命令提示符中键入 cmd /? 以获取更多信息)

【讨论】:

  • 第 2 点不正确。取自 MSDN Do not wait for the child process to exit before reading to the end of its redirected error stream. p.WaitForExit(); Read the error stream first and then wait.
  • @Jehof:你是对的。对不起。我会更新我的帖子。
  • 虽然您(现已删除)的另一点是错误的,但使用 /c 标志实际上有所帮助。谢谢。
【解决方案2】:

RedirectStandardOutput = true;RedirectStandardError = true; 将重定向各自的流。要捕获这些流,您需要按如下方式处理OutputDataReceived 事件:

process.EnableRaisingEvents = true;
process.OutputDataReceived += new DataReceivedEventHandler(process_OutputDataReceived);
process.BeginOutputReadLine();

【讨论】:

    【解决方案3】:

    我正在使用以下代码将进程的 StandardError 和 StandardOutput 打印到调试/控制台

    using (StreamReader reader = process.StandardError) {
      string result = reader.ReadToEnd();
      System.Diagnostics.Debug.Write(result);
    }
    
    using (StreamReader reader = process.StandardOutput) {
      string result = reader.ReadToEnd();
      System.Diagnostics.Debug.Write(result);
    }
    
    process.WaitForExit();
    

    我还在 StartInfo 上设置了以下属性

    StartInfo.UseShellExecute = false;
    StartInfo.ErrorDialog = false;
    StartInfo.RedirectStandardOutput = true;
    StartInfo.RedirectStandardError = true;
    

    【讨论】:

    • 如果您再看一下上面的代码,我已经在StartInfo 上设置了所有这些属性(ErrorDialog 除外)。感谢您的编辑! :)
    • @user1021726 代码是我在应用程序中设置它的方式,用于打印 ffmpeg 的输出,它对我有用。当它适合您时,使用接受的答案中的代码。 :)
    【解决方案4】:

    我认为您正面临documentation 中所述的僵局:

    如果父进程调用 p.StandardOutput.ReadToEnd 后跟 p.StandardError.ReadToEnd 并且子进程写入足够的文本来填充其错误流,则会导致死锁条件。父进程将无限期地等待子进程关闭其 StandardOutput 流。子进程将无限期地等待父进程从完整的 StandardError 流中读取。

    为避免这种情况,您应该对其中一个流使用异步读取操作:

    p.BeginOutputReadLine();
    string error = p.StandardError.ReadToEnd();
    p.WaitForExit();
    

    礼貌应该去MSDN documentation

    【讨论】:

    • 可能。我已经接受了一个答案,该答案也包含在process.BeginOutputReadLine() 中,我认为这有助于解决方案。我不知道进程死锁,所以谢谢!
    【解决方案5】:

    我知道这是旧的,但是当我遇到这个线程时,我想分享我的解决方案。没有答案适合我的需要。我不想在进程结束时读取输出。所以这就是我想出的解决方案。 该解决方案解决了快速响应和慢速响应,因此始终会获得所有输出。

    ...
    process = Process.Start(processInfo);
    process.ErrorDataReceived += (sender, eargs) =>
    {
        // do something
    };
    process.OutputDataReceived += (sender, eargs) =>
    {
        // do something
    
    };
    
    if (timeout > 0)
    {
        // if it is a slow process, read async
        if (!process.WaitForExit(200))
        {
            process.BeginOutputReadLine();
            process.BeginErrorReadLine();
    
            if (!process.WaitForExit(timeout))
            {
                // show error
                return;
            }
    
        } else
        {
            // if it is fast process, need to use "ReadToEnd", because async read will not 
            // caputure output
            var text = process.StandardOutput.ReadToEnd();
            // do something with text
    
        }
        exitCode = process.ExitCode;
    }
    

    【讨论】:

    • 欢迎来到 StackOverflow!请编辑您的答案,并包含一些有关您的解决方案如何工作以及它如何解决您的问题的详细信息。这有助于其他人了解您的解决方案。干杯:)
    猜你喜欢
    • 1970-01-01
    • 2017-06-04
    • 1970-01-01
    • 2018-12-15
    • 1970-01-01
    • 1970-01-01
    • 2019-12-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多