我正在尝试执行命令并等待其退出:
Process proc = new Process();
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.FileName = "cmd.exe";
proc.StartInfo.Arguments = "/c tasklist";
proc.Start();
proc.WaitForExit();
return;
但是,如果tasklist
设置为true,则RedirectStandardOutput
命令永远不会退出。
如果我将RedirectStandardOutput
设置为false或将命令更改为/c whoami
,它将几乎立即退出。
有什么想法吗?
答案 0 :(得分:1)
此代码段应该可以正常运行:
Process proc = new Process();
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.FileName = "cmd.exe";
proc.StartInfo.Arguments = "/c tasklist";
proc.Start();
var output = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
Console.WriteLine(output);
return;
根据MSDN,不读取输出tasklist
的进程将等待直到父进程读取输出为止
如果父进程调用会导致死锁情况
p.WaitForExit
之前的p.StandardOutput.ReadToEnd
和子进程 写足够的文本以填充重定向的流。父进程 将无限期地等待子进程退出。孩子 进程将无限期地等待父级从全文中读取StandardOutput
流。
您还可以像这样异步读取进程输出(并限制进程等待退出超时)
Process proc = new Process();
StringBuilder output = new StringBuilder();
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.FileName = "cmd.exe";
proc.StartInfo.Arguments = "/c tasklist";
proc.OutputDataReceived += (s, e) =>
{
output.Append(e.Data).Append("\n");
};
proc.ErrorDataReceived += (s, e) =>
{
output.Append(e.Data).Append("\n");
};
proc.Start();
proc.BeginOutputReadLine();
proc.WaitForExit(100);
Console.WriteLine(output);
return;
此外,如果您要重定向两个流(错误和输出),则至少要异步读取它们之一,这是由于再次发生了死锁(MSDN链接显示了一个示例)