You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# .NET中如何判断CMD进程执行完成?Robocopy事件异常求助

问题原因及解决办法

核心问题1:未启用进程事件触发开关

Process对象默认不会触发Exited事件,因为EnableRaisingEvents属性默认是false。必须手动开启这个开关,否则即使进程退出,也不会触发绑定的事件方法。

核心问题2:线程可见性隐患

AllCopyComplete是普通布尔变量,Exited事件在后台线程中修改它时,主线程的while循环可能因为CPU缓存优化无法及时感知到变量值的变化,导致循环无法退出。

优化建议:无需通过CMD启动Robocopy

直接启动robocopy.exe进程即可,绕开CMD能更直接地监控Robocopy的状态,还能避免额外的进程开销。


修正后的基础版本代码

// 用volatile修饰,保证多线程下变量的可见性
private volatile bool AllCopyComplete = false;

public void CopyAll()
{
    Log.Info("Performing initial copy of files...");
    string robocopyCommandAll = "/c robocopy <SOURCE> <DEST> /E & exit";
    AllCopyProcess = new Process();
    AllCopyProcess.StartInfo = new ProcessStartInfo("CMD.exe", robocopyCommandAll);
    
    // 关键:开启事件触发开关
    AllCopyProcess.EnableRaisingEvents = true;
    AllCopyProcess.Exited += AllProcessExited;
    
    AllCopyProcess.Start();
    
    while (!AllCopyComplete)
    {
        Log.Info("Waiting (initial copy)...");
        Thread.Sleep(500);
    }
}

private void AllProcessExited(Object sender, EventArgs e)
{
    AllCopyComplete = true;
    Log.Info("All files updated");
}

更高效的进阶版本(直接启动Robocopy)

// 用信号量替代循环Sleep,更高效可靠
private ManualResetEventSlim copyCompletedSignal = new ManualResetEventSlim(false);

public void CopyAll()
{
    Log.Info("Performing initial copy of files...");
    AllCopyProcess = new Process();
    // 直接启动robocopy.exe,无需通过CMD中转
    AllCopyProcess.StartInfo = new ProcessStartInfo("robocopy.exe", "<SOURCE> <DEST> /E")
    {
        CreateNoWindow = true, // 可选:避免弹出命令行窗口
        UseShellExecute = false // 若需要重定向输出则必须设为false
    };
    
    AllCopyProcess.EnableRaisingEvents = true;
    AllCopyProcess.Exited += (sender, e) =>
    {
        var process = (Process)sender;
        copyCompletedSignal.Set();
        // Robocopy退出码有特殊含义:0=无文件复制,1=复制成功,2=存在文件差异等
        Log.Info($"All files updated. Robocopy exit code: {process.ExitCode}");
    };
    
    AllCopyProcess.Start();
    
    // 等待信号量触发,替代低效的Sleep循环
    copyCompletedSignal.Wait();
    copyCompletedSignal.Dispose();
}

内容的提问来源于stack exchange,提问作者Inglonias

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 19:32:41