在进程中调用 robocopy 的批处理脚本不会终止

2023-12-09

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(使用前将#替换为@)

在进程中调用 robocopy 的批处理脚本不会终止 的相关文章

随机推荐