If process.Kill()
从另一个线程甚至另一个程序调用,该进程永远不会出来WaitForExit()
如果批处理脚本使用 robocopy.exe 直到它完成,就好像它没有被杀死一样。
Robocopy.exe 从批处理脚本中调用。所有其他脚本或程序都会按您的预期结束。
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "batch.bat";
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardOutput = true;
startInfo.OutputDataReceived += CaptureHandler;
startInfo.RedirectStandardError = true;
startInfo.ErrorDataReceived += CaptureHandler;
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
批处理脚本如下所示:
@echo off
call "robocopy.exe" "somedir" "somedest" /mir /fp /ndl /njh /njs /ns
我有一种感觉,这与输出处理程序有关。
我尝试使用process.CancelErrorRead
and process.CancelOutputRead()
以及之后Kill()
之前打电话,没有运气。
奇怪的是,如果你使用process.WaitForExit(timeout)
重载后立即返回 trueKill()
来自另一个线程。然而,它是在撒谎。该进程仍在运行!如果你试试process.WaitForExit()
再次,根据 MSDN 文档,尽管如此,它仍然会等待该过程完成HasExited
说的是真的。
要确保异步事件处理已完成,请在从此重载中收到 true 后调用不带任何参数的 WaitForExit() 重载。
https://msdn.microsoft.com/en-us/library/ty0d8k56(v=vs.110).aspx
您已成功终止批处理处理器 (cmd.exe),但这样做不会终止 robocopy,这是一个单独的进程。
It 似乎没有记录, but 当我们查看.NET源代码时事实证明Process.WaitForExit()
方法没有just等待进程退出,就可以了also等待标准输出和标准错误流上的文件结尾。在这种情况下,这意味着即使批处理器被终止,它也会等待 robocopy 完成。
(过载Process.WaitForExit
超时则没有这个额外的逻辑。)
我认为这是 .NET 框架中的一个错误。至少,应该记录下来。
作为解决方法,您可以使用.HasExited
和/或版本WaitForExit
使用超时来确定进程是否已退出。当然,在你的场景中你可能prefer等待孙子进程,在这种情况下,您的代码已经按预期运行。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)