无法从cmd获得输出

时间:2014-03-13 08:02:51

标签: c# process cmd output stdout

我正在运行

        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线程并做了相当多的谷歌搜索,但我无法让它工作。

5 个答案:

答案 0 :(得分:3)

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

  

/ C执行string指定的命令,然后终止

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

答案 1 :(得分:2)

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

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

答案 2 :(得分:1)

我使用以下代码将Process的StandardError和StandardOutput打印到Debug / Console

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;

答案 3 :(得分:1)

我认为你正面临着documentation

中描述的僵局
  

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

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

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

礼貌应该转到MSDN documentation

答案 4 :(得分:0)

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

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