2009-04-14 9 views
5

나는 WMI to start a process on a remote machine을 사용하고 있습니다. 프로세스를 생성하는 호출이 즉시 반환되며 원격 시스템에서 프로세스의 ID도 얻습니다.원격 컴퓨터의 프로세스 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

uWatcher와 MBOobj를 "using"상태로 랩핑해야합니다. – Simon

2

것이 달성의 네이티브는 Win32 방법은 과정에 WaitForSingleObject()을 수행 할 : 그냥 추가 정보

이 내가 현재 원격 프로세스를 시작하는 데 사용하고있는 코드입니다 CreateProcess() 그러나이 핸들은 WMI에서 사용할 수 있다고 생각하지 않습니다.

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 

당신은 할 수 : 대신 폴링의 프로세스 목록과 프로세스가 사라질 때까지 기다리고, 그것은 반복 프로세스의 ID와 일치하는 프로세스 삭제 이벤트에 대한 쿼리 -

This article

당신이 고려할 수 있습니다 또 다른 옵션을 제공합니다 또한 ManagementEventWatcher 개체와 그 WaitForNextEvent 메서드를 사용하여 삭제 이벤트를 폴링하지 않아도됩니다.

1

.

원격 프로세스에이 방법을 사용하려면 프로세스를 모니터링하고 완료된 ping을 반환하는 원격 컴퓨터에 도우미 응용 프로그램/서비스가 있어야합니다. 아직이를 확인할 기회가 havent 한

+0

감사합니다. 좋은 생각입니다. 이것은 아마도 가장 효율적이고 매우 간단합니다. 그러나 모든 프로세스를 원격으로 시작할 수 있도록 최대한 일반화하고 싶습니다. –

0

,

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

프로세스 remPrc = Process.GetProcessById (pid, RemoteMachine);

remPrc.WaitForExit();

+0

유감스럽게도 Unfortunatley – Derek

관련 문제