无法从cmd获取输出

问题描述 投票:1回答:5

我正在运行此

        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线程,并做了很多谷歌搜索,但我无法使其正常工作。

c# process cmd output stdout
5个回答
2
投票

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

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

3
投票

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

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

((在命令提示符下输入cmd /?以获得更多信息)


1
投票

我正在使用以下代码将进程的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;

1
投票

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

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

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

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

礼貌应转到MSDN documentation


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;
}
© www.soinside.com 2019 - 2024. All rights reserved.