2009-04-14 3 views
5

Ich verwende WMI to start a process on a remote machine. Der Aufruf zum Erstellen des Prozesses wird sofort zurückgegeben und ich erhalte auch die ID des Prozesses auf dem Remotecomputer.WaitForExit für einen Prozess auf einem Remote-Computer

Ich möchte warten, bis der Remote-Prozess abgeschlossen ist. Eine Option wäre, abzufragen, ob ein Prozess auf dem entfernten Rechner mit der angegebenen ID noch existiert.

Allerdings habe ich mich gefragt, ob es einen besseren Weg gibt, dies zu erreichen, vielleicht mit nativen WinAPI-Funktionen?

Nur für zusätzliche Informationen, das ist der Code, den ich zur Zeit den Remote-Prozess starten bin mit:

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); 

Antwort

4

Ich weiß nicht, wie effektiv dies sein kann, können Sie ManagementEventWatcher verwenden, um eine Abfrage zu sehen.

Hier ist etwas, was ich im Netz gefunden habe.

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

du solltest wWatcher und MBOobj in einen "using" statesmen einbinden – Simon

2

Die native Win32-Weg, dies zu erreichen, wäre eine WaitForSingleObject() auf den Prozess auszuführen zurückgegebene Handle durch CreateProcess(), aber ich denke nicht, dass dieser Griff Ihnen von WMI zur Verfügung gestellt wird.

This article bietet eine weitere Option, die Sie in Erwägung ziehen könnte - statt Polliste den Prozess und wartet auf Ihren Prozess, verschwinden sie fragt immer wieder für Veranstaltungen Prozess Löschung Ihrer Prozess-ID übereinstimmt, gefunden

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 

konnte Sie Verbessern Sie dies auch, indem Sie ein ManagementEventWatcher Objekt und seine WaitForNextEvent Methode verwenden, um zu vermeiden, dass Sie nach Löschvorgängen suchen müssen.

1

Wenn der Prozess auf dem entfernten Rechner den Code dann könnte man die Remote-Maschine ‚Ping‘ eine Buchse an der anrufenden Maschine und lassen sich öffnen, wenn es fertig ist.

Wenn Sie diese Methode für einen Remote-Prozess verwenden möchten, können Sie eine Hilfsanwendung/einen Hilfsdienst auf dem Remotecomputer verwenden, der Ihren Prozess überwacht und den abgeschlossenen Ping zurückgibt.

+0

Das ist eine nette Idee, danke. Dies wäre wahrscheinlich am effizientesten und ziemlich einfach. Ich möchte es jedoch so allgemein wie möglich halten, damit ich jeden Prozess aus der Ferne starten kann. –

0

ich Chance haben hatte dies noch zu prüfen,

int pid = (int) Managementbase [ "processId"];

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

remPrc.WaitForExit();

+0

funktioniert leider nicht – Derek

Verwandte Themen