2009-04-14 13 views
5

Estoy usando WMI to start a process on a remote machine. La llamada para crear el proceso vuelve inmediatamente y también obtengo la identificación del proceso en la máquina remota.WaitForExit para un proceso en una computadora remota

Me gustaría esperar a que se complete el proceso remoto. Una opción sería sondear si aún existe un proceso en la máquina remota con la identificación dada.

Sin embargo, me preguntaba si hay una mejor manera de lograr esto, tal vez usando funciones WinAPI nativas.

Sólo para obtener información adicional, este es el código que estoy utilizando actualmente para iniciar el proceso remoto:

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

Respuesta

4

No sé cuán efectivo puede ser esto, puede usar ManagementEventWatcher para ver una consulta.

Aquí hay algo que encontré en la red.

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

u debe envolver wWatcher y MBOobj en un estado "en uso" – Simon

2

La forma nativa de Win32 de conseguir esto sería llevar a cabo una WaitForSingleObject() en el proceso identificador devuelto por CreateProcess(), sin embargo, no creo que este identificador esté disponible para usted en WMI.

This article ofrece otra opción que podría considerar - lugar de sondear la lista de procesos ya la espera de su proceso de desaparecer, que consultas repetidas ocasiones para eventos proceso de eliminación que coincidan con su identificador de proceso:

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 

Usted podría también mejore esto usando un objeto ManagementEventWatcher y su método WaitForNextEvent para evitar tener que sondear para los eventos de eliminación.

1

Si el proceso en la máquina remota es su código entonces se podría abrir una conexión con la máquina llamada y dejar que la máquina remota 'ping' que cuando se ha terminado.

Si desea utilizar este método para cualquier proceso remoto, podría tener una aplicación/servicio de ayuda en la computadora remota que monitorea su proceso y devuelve el ping completado.

+0

Esa es una buena idea, gracias. Esto probablemente sería más eficiente y bastante simple. Sin embargo, me gustaría mantenerlo tan genérico como sea posible para que pueda iniciar cualquier proceso de forma remota. –

0

No he oportunidad de comprobar esto todavía tenía,

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

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

remPrc.WaitForExit();

+0

Doesnt Work Unfortunatley – Derek

Cuestiones relacionadas