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

如何使用PsExec同步在多台PC上运行EXE程序?

刚好之前帮团队解决过类似的多机精准同步启动程序的问题,PsExec本身的串行执行逻辑确实会因为网络延迟、目标机启动速度差异导致不同步,给你几个经过验证的方案,从简单到进阶都有:

方案一:时间触发式同步(最易实现)

核心思路是先让所有目标机的系统时间精确同步,然后让它们在同一个预设时间点启动程序,完全规避命令发送的延迟问题。

  • 第一步:批量同步所有目标机的系统时间
    在控制机上执行命令,强制每台目标机同步到时间服务器:

    @echo off
    setlocal enabledelayedexpansion
    for /f %%i in (machines.txt) do (
        w32tm /resync /computer:%%i /force
        echo 已同步 %%i 的时间
    )
    

    其中machines.txt是你的目标机IP/主机名列表,每行一个。

  • 第二步:创建定时启动任务
    先计算一个未来的时间点(比如当前时间加30秒,给所有机器足够的任务创建时间),然后在每台机器上创建一次性定时任务:

    @echo off
    :: 获取当前时间并计算30秒后的时间(格式HH:MM:SS)
    for /f "tokens=1-3 delims=:" %%a in ("%time%") do (
        set /a "sec=%%c+30"
        set /a "min=%%b+sec/60"
        set /a "sec=sec%%60"
        set /a "hour=%%a+min/60"
        set /a "min=min%%60"
        set "starttime=!hour!:!min!:!sec!"
    )
    :: 确保时间格式补零(比如9秒变成09)
    set starttime=%starttime: =0%
    
    :: 批量创建定时任务
    for /f %%i in (machines.txt) do (
        schtasks /create /s %%i /tn "TempSyncStart" /tr "C:\路径\你的程序.exe" /sc once /st %starttime% /f
        echo 已为 %%i 设置启动任务
    )
    
  • 第三步:清理临时任务(可选)
    程序启动后,可以批量删除这个临时任务避免残留:

    for /f %%i in (machines.txt) do (
        schtasks /delete /s %%i /tn "TempSyncStart" /f
        echo 已清理 %%i 的临时任务
    )
    
方案二:信号触发式同步(精准度最高)

如果需要毫秒级的同步精度,可以用「先加载程序到内存挂起,再统一发送启动信号」的方式,完全消除启动延迟差异。

步骤1:编写一个简单的同步启动辅助程序

用C#写一个小工具,负责启动目标程序但先挂起,等待全局信号后再恢复运行:

using System;
using System.Diagnostics;
using System.Threading;

namespace SyncStarter
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.WriteLine("请传入目标程序路径");
                return;
            }

            // 启动目标程序并立即挂起
            ProcessStartInfo startInfo = new ProcessStartInfo(args[0])
            {
                CreateNoWindow = false, // 根据你的程序需求调整
                UseShellExecute = false
            };
            Process targetProcess = Process.Start(startInfo);
            targetProcess.Suspend();

            // 等待全局同步信号
            using (EventWaitHandle syncEvent = new EventWaitHandle(
                false, 
                EventResetMode.ManualReset, 
                "Global\\MultiMachineSyncEvent"))
            {
                syncEvent.WaitOne();
            }

            // 恢复目标程序运行
            targetProcess.Resume();
        }
    }
}

编译成SyncStarter.exe,放到所有目标机的同一个路径下(比如C:\Tools\)。

步骤2:批量加载程序到内存

用PsExec在所有目标机上启动辅助程序,此时你的目标程序已经被加载但处于挂起状态:

psexec @machines.txt -c C:\Tools\SyncStarter.exe "C:\你的程序.exe"

步骤3:发送全局启动信号

用PsExec在所有机器上触发全局事件,所有挂起的程序会瞬间恢复运行:

psexec @machines.txt powershell -Command "New-EventWaitHandle -Name 'Global\\MultiMachineSyncEvent' -InitialState $true -ResetMode ManualReset"
方案三:并行化PsExec调用(低成本优化)

如果只是想最小化PsExec串行执行的延迟,可以用PowerShell并行启动多个PsExec进程,让命令几乎同时发送到所有目标机:

# 读取目标机列表
$machineList = Get-Content "machines.txt"
# 你的程序路径
$targetExe = "C:\路径\你的程序.exe"

# 并行启动PsExec命令
foreach ($machine in $machineList) {
    Start-Process -FilePath "psexec.exe" -ArgumentList "\\$machine $targetExe" -NoNewWindow -PassThru
}

这种方式比传统的串行批处理时间差小很多,但精度不如前两种方案,适合对同步要求不是特别极端的场景。


额外注意事项

  • 确保所有目标机的防火墙允许PsExec的通信(默认用445端口),避免网络延迟过大。
  • 测试时可以用一个显示当前时间戳的测试程序,来验证同步效果。
  • 时间同步是所有方案的基础,建议把目标机配置为自动同步企业内部时间服务器。

内容的提问来源于stack exchange,提问作者Sebastián Pellegrino

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:04:16