我正在使用WMI to start a process on a remote machine。创建进程的调用立即返回,我也在远程计算机上获取进程的id。
我想等待远程进程完成。一种选择是轮询具有给定id的远程机器上的进程是否仍然存在。
但是,我想知道是否有更好的方法来实现这一点,可能使用原生的WinAPI函数?
仅为了解更多信息,这是我目前用于启动远程进程的代码:
ConnectionOptions connOptions = new ConnectionOptions();
connOptions.Impersonation = ImpersonationLevel.Impersonate;
connOptions.EnablePrivileges = true;
connOptions.Username = domainUserName;
connOptions.Password = password;
ManagementScope manScope = new ManagementScope(String.Format(@"\\{0}\ROOT\CIMV2", host), connOptions);
manScope.Connect();
ObjectGetOptions objectGetOptions = new ObjectGetOptions();
ManagementPath managementPath = new ManagementPath("Win32_Process");
ManagementClass processClass = new ManagementClass(manScope, managementPath, objectGetOptions);
ManagementBaseObject inParams = processClass.GetMethodParameters("Create");
inParams["CommandLine"] = commandLine;
ManagementBaseObject outParams = processClass.InvokeMethod("Create", inParams, null);
答案 0 :(得分:4)
我不知道这有多有效,您可以使用ManagementEventWatcher来查看查询。
这是我在网上找到的东西。
WqlEventQuery wQuery =
new WqlEventQuery("Select * From __InstanceDeletionEvent Within 1 Where TargetInstance ISA 'Win32_Process'");
using (ManagementEventWatcher wWatcher = new ManagementEventWatcher(scope, wQuery))
{
bool stopped = false;
while (stopped == false)
{
using (ManagementBaseObject MBOobj = wWatcher.WaitForNextEvent())
{
if (((ManagementBaseObject)MBOobj["TargetInstance"])["ProcessID"].ToString() == ProcID)
{
// the process has stopped
stopped = true;
}
}
}
wWatcher.Stop();
}
答案 1 :(得分:2)
实现此目的的本机Win32方法是对WaitForSingleObject()
返回的进程句柄执行CreateProcess()
,但我不认为WMI可以使用此句柄。
This article提供了您可以考虑的另一个选项 - 它不是轮询流程列表并等待您的流程消失,而是反复查询与您的流程ID匹配的流程删除事件:
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2:Win32_Process")
objWMIService.Create "notepad.exe", null, null, intProcessID
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colMonitoredProcesses = objWMIService.ExecNotificationQuery _
("Select * From __InstanceDeletionEvent Within 1 Where TargetInstance ISA 'Win32_Process'")
Do Until i = 1
Set objLatestProcess = colMonitoredProcesses.NextEvent
If objLatestProcess.TargetInstance.ProcessID = intProcessID Then
i = 1
End If
Loop
您还可以通过使用ManagementEventWatcher
对象及其WaitForNextEvent
方法来改进此操作,以避免必须轮询删除事件。
答案 2 :(得分:1)
如果远程计算机上的进程是您的代码,那么您可以在调用计算机上打开一个套接字,让远程计算机在完成后“ping”它。
如果要将此方法用于任何远程进程,您可以在远程计算机上拥有一个帮助程序/服务来监视您的进程并返回已完成的ping。
答案 3 :(得分:0)
我还没有机会检查这个,
int pid =(int)managementBaseObject [“processId”];
处理remPrc = Process.GetProcessById(pid,RemoteMachine);
remPrc.WaitForExit();