[英]WaitForExit for a process on a remote computer
I'm using WMI to start a process on a remote machine . 我正在使用WMI在远程计算机上启动进程 。 The call to create the process returns immediately and I also get the id of the process on the remote machine. 创建进程的调用立即返回,我也在远程计算机上获取进程的id。
I would like to wait for the remote process to be completed. 我想等待远程进程完成。 One option would be to poll whether a process on the remote machine with the given id still exists. 一种选择是轮询具有给定id的远程机器上的进程是否仍然存在。
However, I was wondering whether there is a better way to achieve this, maybe using native WinAPI functions? 但是,我想知道是否有更好的方法来实现这一点,可能使用本机WinAPI函数?
Just for additional information, this is the code that I am currently using to start the remote process: 仅用于获取更多信息,这是我目前用于启动远程进程的代码:
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);
I don't know how effective this can be, you can use ManagementEventWatcher to watch a query. 我不知道这有多有效,您可以使用ManagementEventWatcher来查看查询。
Here is something I found on the net. 这是我在网上找到的东西。
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();
}
The native Win32 way of achieving this would be to perform a WaitForSingleObject()
on the process handle returned by CreateProcess()
, however I don't think this handle is made available to you from WMI. 实现此目的的本机Win32方法是在CreateProcess()
返回的进程句柄上执行WaitForSingleObject()
CreateProcess()
,但是我不认为WMI可以使用此句柄。
This article offers another option you could consider - instead of polling the process list and waiting for your process to disappear, it repeatedly queries for process deletion events matching your process ID: 本文提供了您可以考虑的另一个选项 - 它不是轮询进程列表并等待进程消失,而是反复查询与进程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
You could also improve on this by using a ManagementEventWatcher
object and its WaitForNextEvent
method to avoid having to poll for the deletion events. 您还可以通过使用ManagementEventWatcher
对象及其WaitForNextEvent
方法来改进此操作,以避免必须轮询删除事件。
If the process on the remote machine is your code then you could open up a socket on the calling machine and let the remote machine 'ping' it when it has finished. 如果远程计算机上的进程是您的代码,那么您可以在调用计算机上打开一个套接字,让远程计算机在完成后“ping”它。
If you want to use this method for any remote process you could have a helper app/service on the remote computer that monitors your process and returns the completed ping. 如果要将此方法用于任何远程进程,则可以在远程计算机上使用帮助程序/服务来监视进程并返回已完成的ping。
I havent had chance to check this yet, 我还没有机会检查这个,
int pid = (int)managementBaseObject["processId"]; int pid =(int)managementBaseObject [“processId”];
Process remPrc = Process.GetProcessById(pid, RemoteMachine); 进程remPrc = Process.GetProcessById(pid,RemoteMachine);
remPrc.WaitForExit(); remPrc.WaitForExit();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.