C#如何从远程服务器调用可执行文件并在远程客户端运行?
实现从远程服务器推送可执行文件到客户端并运行的C#方案
嘿,我来帮你搞定这个问题!你现在的需求是把服务器端的可执行文件推送到远程客户端,然后在那边执行对吧?核心其实就是两步:先上传文件到远程机器,再触发执行。下面给你几个实用的C#实现方案,都是实际场景里验证过的:
方案一:用Windows原生WMI(推荐域内环境)
WMI是Windows自带的管理工具,不需要在客户端额外安装软件,适合企业域内的Windows机器。步骤如下:
1. 先将服务器上的文件复制到远程机器
如果远程机器开启了文件共享(比如默认的C$共享),可以直接用System.IO.File.Copy配合UNC路径完成上传:
string localExePath = @"C:\ServerFiles\MyApp.exe"; string remoteExePath = @"\\RemoteMachineName\C$\Temp\MyApp.exe"; // 确保远程目录存在 string remoteDir = Path.GetDirectoryName(remoteExePath); if (!Directory.Exists(remoteDir)) { Directory.CreateDirectory(remoteDir); } // 复制文件到远程 File.Copy(localExePath, remoteExePath, overwrite: true);
2. 通过WMI启动远程机器上的可执行文件
接下来用WMI连接远程机器,调用Win32_Process.Create方法启动刚才上传的exe:
ConnectionOptions options = new ConnectionOptions(); options.Username = "RemoteMachineAdminUser"; options.Password = "RemoteMachinePassword"; options.Impersonation = ImpersonationLevel.Impersonate; ManagementScope scope = new ManagementScope(@"\\RemoteMachineName\root\cimv2", options); scope.Connect(); ObjectGetOptions getOptions = new ObjectGetOptions(); ManagementClass processClass = new ManagementClass(scope, new ManagementPath("Win32_Process"), getOptions); ManagementBaseObject inParams = processClass.GetMethodParameters("Create"); inParams["CommandLine"] = @"C:\Temp\MyApp.exe"; // 远程机器上的exe路径 // 执行启动命令 ManagementBaseObject outParams = processClass.InvokeMethod("Create", inParams, null); uint returnValue = (uint)outParams["ReturnValue"]; if (returnValue == 0) { Console.WriteLine("远程进程启动成功!"); } else { Console.WriteLine($"启动失败,错误码:{returnValue}"); }
方案二:用SSH.NET(适合跨平台/非域环境)
如果你的远程机器是Linux或者非域内的Windows(开启了SSH服务),可以用SSH.NET库来实现SFTP上传+SSH执行命令:
1. 安装SSH.NET包
先通过NuGet安装SSH.NET:
Install-Package SSH.NET
2. 上传文件并执行
using Renci.SshNet; string sshHost = "RemoteMachineIP"; string sshUser = "SshUsername"; string sshPassword = "SshPassword"; // 上传文件到远程机器 using (var sftp = new SftpClient(sshHost, sshUser, sshPassword)) { sftp.Connect(); using (var fileStream = new FileStream(@"C:\ServerFiles\MyApp.exe", FileMode.Open)) { sftp.UploadFile(fileStream, "/home/user/MyApp.exe"); // Windows环境可改为C:\\Temp\\MyApp.exe } sftp.Disconnect(); } // 执行远程命令启动exe using (var sshClient = new SshClient(sshHost, sshUser, sshPassword)) { sshClient.Connect(); var command = sshClient.RunCommand(@"C:\Temp\MyApp.exe"); // Linux环境可改为./MyApp.exe Console.WriteLine($"命令输出:{command.Result}"); sshClient.Disconnect(); }
方案三:封装PsExec工具(快速实现)
如果你不想写太多代码,可以用Sysinternals的PsExec工具,它可以直接从服务器推送文件到远程机器并执行。C#里可以通过Process.Start调用PsExec:
string psexecPath = @"C:\Tools\PsExec.exe"; string remoteMachine = "RemoteMachineName"; string localExe = @"C:\ServerFiles\MyApp.exe"; string remoteArgs = ""; // 可执行文件的启动参数 ProcessStartInfo psi = new ProcessStartInfo(psexecPath); psi.Arguments = $"\\\\{remoteMachine} -c {localExe} {remoteArgs}"; psi.WindowStyle = ProcessWindowStyle.Hidden; using (Process process = Process.Start(psi)) { process.WaitForExit(); Console.WriteLine($"PsExec执行退出码:{process.ExitCode}"); }
注意事项
- 权限问题:不管用哪种方案,都需要远程机器的管理员权限,确保账户有文件写入和进程启动的权限。
- 防火墙设置:WMI需要开放135端口和动态RPC端口;SMB需要开放445端口;SSH需要开放22端口,确保远程机器的防火墙允许这些流量。
- 文件覆盖:上传文件时记得处理已存在的文件,避免冲突。
内容的提问来源于stack exchange,提问作者JeffS
相关产品推荐
相关产品推荐

