2009-04-14 2 views
5

Я использую WMI to start a process on a remote machine. Вызов для создания процесса немедленно возвращается, и я также получаю идентификатор процесса на удаленной машине.WaitForExit для процесса на удаленном компьютере

Я хотел бы дождаться завершения удаленного процесса. Один из вариантов - опросить, существует ли процесс на удаленном компьютере с данным идентификатором.

Однако мне было интересно, есть ли лучший способ достичь этого, возможно, используя собственные функции 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

u должен обернуть wWatcher и MBOobj в «использование» statemen – Simon

2

Уроженец Win32 способ достижения этой цели было бы выполнить WaitForSingleObject() на процесс ручки, возвращенное CreateProcess(), однако я не думаю, что этот дескриптор доступен вам от WMI.

This article предлагает еще один вариант можно рассмотреть - вместо опроса списка процессов и ждет ваш процесс исчезнет, ​​он неоднократно запрашивает для удаления процесса событий, соответствующих заданным вами идентификатор процесса:

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

Если процесс на удаленной машине ваш код, то вы можете открыть сокет на вызывающей машине, и пусть удаленную машину «пинг», когда он закончил.

Если вы хотите использовать этот метод для любого удаленного процесса, у вас может быть вспомогательное приложение/служба на удаленном компьютере, который контролирует ваш процесс и возвращает завершенный пинг.

+0

Это хорошая идея, спасибо. Это, вероятно, будет наиболее эффективным и достаточно простым. Тем не менее, я хотел бы сохранить его как можно более общим, чтобы я мог начать любой процесс удаленно. –

0

я гавань была возможность проверить это еще,

INT PID = (INT) managementBaseObject [ "ProcessId"];

Процесс remPrc = Process.GetProcessById (pid, RemoteMachine);

remPrc.WaitForExit();

+0

Не работает Unfortunatley – Derek

Смежные вопросы