2009-04-14 32 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