如何在远程机器上执行进程,在 C# 中
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2343677/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to execute process on remote machine, in C#
提问by DJPB
How can I start a process on a remote computer in c#, say computer name = "someComputer", using System.Diagnostics.Process class?
如何使用 System.Diagnostics.Process 类在 c# 中的远程计算机上启动进程,例如计算机名称 =“someComputer”?
I created a small console app on that remote computer that just writes "Hello world" to a txt file, and I would like to call it remotely.
我在那台远程计算机上创建了一个小型控制台应用程序,它只是将“Hello world”写入一个 txt 文件,我想远程调用它。
Console app path: c:\MyAppFolder\MyApp.exe
控制台应用程序路径:c:\MyAppFolder\MyApp.exe
Currently I have this:
目前我有这个:
ProcessStartInfo startInfo = new ProcessStartInfo(string.Format(@"\{0}\{1}", someComputer, somePath);
startInfo.UserName = "MyUserName";
SecureString sec = new SecureString();
string pwd = "MyPassword";
foreach (char item in pwd)
{
sec.AppendChar(item);
}
sec.MakeReadOnly();
startInfo.Password = sec;
startInfo.UseShellExecute = false;
Process.Start(startInfo);
I keep getting "Network path was not found".
我不断收到“找不到网络路径”的消息。
回答by Ivan G.
Can can use PsExec from http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx
可以从http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx使用 PsExec
Or WMI:
或 WMI:
object theProcessToRun() = { "YourFileHere" };
ManagementClass theClass = new ManagementClass(@"\server\root\cimv2:Win32_Process");
theClass.InvokeMethod("Create", theProcessToRun);
回答by F3.
I don't believe you can start a process through a UNC path directly; that is, if System.Process uses the windows comspec to launch the application... how about you test this theory by mapping a drive to "\someComputer\somePath", then changing your creation of the ProcessStartInfo to that? If it works that way, then you may want to consider temporarily mapping a drive programmatically, launch your app, then remove the mapping (much like pushd/popd works from a command window).
我不相信你可以直接通过 UNC 路径启动一个进程;也就是说,如果 System.Process 使用 windows comspec 来启动应用程序......你如何通过将驱动器映射到“\someComputer\somePath”来测试这个理论,然后将你的 ProcessStartInfo 创建更改为那个?如果它以这种方式工作,那么您可能需要考虑以编程方式临时映射驱动器,启动您的应用程序,然后删除映射(很像 pushd/popd 从命令窗口工作)。
回答by Austin Salonen
回答by Seva Alekseyev
Use one of the following:
使用以下方法之一:
- (EDIT) Remote Powershell
- WMI (see Ivan G's answer)
- Task Scheduler API (http://msdn.microsoft.com/en-us/library/windows/desktop/aa383606%28v=vs.85%29.aspx)
- PsExec
- WshRemoteobject with a dummy script. Chances are, it works via DCOM, activating some of scripting objects remotely.
- (编辑)远程 Powershell
- WMI(见 Ivan G 的回答)
- 任务计划程序 API ( http://msdn.microsoft.com/en-us/library/windows/desktop/aa383606%28v=vs.85%29.aspx)
- 执行程序
- 带有虚拟脚本的WshRemote对象。很有可能,它通过 DCOM 工作,远程激活一些脚本对象。
Or if you feel like it, inject your own service or COM component. That would be very close to what PsExec does.
或者,如果您愿意,可以注入您自己的服务或 COM 组件。这与 PsExec 所做的非常接近。
Of all these methods, I prefer task scheduler. The cleanest API of them all, I think. Connect to the remote task scheduler, create a new task for the executable, run it. Note: the executable name should be local to thatmachine. Not \servername\path\file.exe, but c:\path\file.exe. Delete the task if you feel like it.
在所有这些方法中,我更喜欢任务调度程序。我认为它们中最干净的 API。连接到远程任务调度程序,为可执行文件创建一个新任务,运行它。注意:可执行文件名称应该是该机器的本地名称。不是\servername\path\file.exe,而是c:\path\file.exe。如果您愿意,请删除该任务。
All those methods require that you have administrative access to the target machine.
所有这些方法都要求您具有对目标计算机的管理访问权限。
ProcessStartInfo
is not capable of launching remote processes.
ProcessStartInfo
无法启动远程进程。
回答by live2
An example with WMI and other credentials as the current process, on default it used the same user as the process runs.
使用 WMI 和其他凭据作为当前进程的示例,默认情况下它使用与进程运行相同的用户。
var hostname = "server"; //hostname or a IpAddress
var connection = new ConnectionOptions();
//The '.\' is for a local user on the remote machine
//Or 'mydomain\user' for a domain user
connection.Username = @".\Administrator";
connection.Password = "passwordOfAdministrator";
object[] theProcessToRun = { "YourFileHere" }; //for example notepad.exe
var wmiScope = new ManagementScope($@"\{hostname}\root\cimv2", connection);
wmiScope.Connect();
using (var managementClass = new ManagementClass(wmiScope, new ManagementPath("Win32_Process"), new ObjectGetOptions()))
{
managementClass.InvokeMethod("Create", theProcessToRun);
}