简体   繁体   English

WaitForExit用于远程计算机上的进程

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM