无法从cmd获取输出
本文关键字:获取 输出 cmd | 更新日期: 2023-09-27 17:49:48
我正在运行这个
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
选项来cmd.exe
,否则子进程将无法退出。
/C执行string指定的命令,然后终止
(在命令提示符中输入cmd /?
以获取更多信息)
RedirectStandardOutput = true;
和RedirectStandardError = true;
将重定向各自的流。要捕获这些流,您需要按如下方式处理OutputDataReceived
事件:
process.EnableRaisingEvents = true;
process.OutputDataReceived += new DataReceivedEventHandler(process_OutputDataReceived);
process.BeginOutputReadLine();
我使用以下代码将进程的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;
我认为您正面临文档中所描述的死锁:
如果父进程调用p.s ardoutput . readtoend和p.s arderror . readtoend,并且子进程写入足够的文本来填充其错误流,则会导致死锁条件。父进程将无限期地等待子进程关闭其StandardOutput流。子进程将无限期地等待父进程从完整的标准错误流中读取。
为了避免这种情况,你应该在其中一个流上使用异步读操作:
p.BeginOutputReadLine();
string error = p.StandardError.ReadToEnd();
p.WaitForExit();
请查看MSDN文档
我知道这是旧的,但我想分享我的解决方案,当我遇到这个线程。没有适合我需要的答案。我不想在进程结束时读取输出。这就是我想出来的解决方案。该解决方案可同时解决快速和慢速响应,因此将始终获得所有输出。
...
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;
}