当 RedirectStandardOutput 为 true 时,tasklist 命令不会退出
Posted
技术标签:
【中文标题】当 RedirectStandardOutput 为 true 时,tasklist 命令不会退出【英文标题】:tasklist command won't exit when RedirectStandardOutput is true 【发布时间】:2020-02-03 21:11:51 【问题描述】:我正在尝试执行一个命令并等待它退出:
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;
但是,如果 RedirectStandardOutput
设置为 true,tasklist
命令永远不会退出。
如果我将RedirectStandardOutput
设置为false 或将命令更改为/c whoami
,它几乎会立即退出。
有什么想法吗?
【问题讨论】:
在proc.Start();
和proc.WaitForExit();
之间插入console.WriteLine(proc.StandardOutput.ReadToEnd());
@JosefZ 添加 ReadToEnd() 有效。但我还需要限制使用proc.StandardOutput.Read()
读取的最大字节数。如果我在WaitForExit()
之前调用Read()
,我将得到部分输出;如果我先做WaitForExit()
,它会卡住
【参考方案1】:
您应该在调用WaitForExit()
之前阅读输出,此示例工作正常:
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;
不读取输出tasklist
进程等待直到父进程读取输出,根据RedirectStandardOutput
的备注部分
如果父进程调用可能会导致死锁情况
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 链接显示了一个示例)
【讨论】:
以上是关于当 RedirectStandardOutput 为 true 时,tasklist 命令不会退出的主要内容,如果未能解决你的问题,请参考以下文章