2009-04-14 94 views
5

我正在使用WMI to start a process on a remote machine。创建进程的调用会立即返回,并且我还会获得远程计算机上进程的标识。WaitForExit用于远程计算机上的进程

我想等待远程过程完成。一种选择是查询具有给定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); 

回答

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(); 
} 
+0

你应该将wWatcher和MBOobj包装在“使用”状态中 – Simon 2011-09-15 00:40:35

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方法来改善此问题,以避免必须轮询删除事件。

1

如果远程计算机上的进程是你的代码,那么你可以打开调用机器上的插座,并让远程机器“平”它时,它已经完成。

如果您希望对任何远程进程使用此方法,则可以在远程计算机上安装助手应用程序/服务,以监控您的进程并返回完成的ping。

+0

这是个好主意,谢谢。这可能是最高效和非常简单的。但是,我想尽可能保持通用,以便可以远程启动任何进程。 – 2009-04-15 09:04:24

0

我还不得不机会尚未检查此,

INT PID =(int)的managementBaseObject [ “的ProcessID”];

Process remPrc = Process.GetProcessById(pid,RemoteMachine);

remPrc.WaitForExit();

+0

没有工作Unfortunatley – Derek 2012-05-02 10:48:04

相关问题