2009-04-14 12 views
5

私はWMI to start a process on a remote machineを使用しています。プロセスを作成するための呼び出しはすぐに戻り、リモート・マシン上のプロセスのIDも取得します。リモートコンピュータ上のプロセスのWaitForExit

私はリモートプロセスが完了するのを待っています。 1つのオプションは、指定された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

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を実行に "それをしましょう。

リモートプロセスでこのメソッドを使用する場合は、プロセスを監視して完了したpingを返すリモートコンピュータ上にヘルパーアプリケーション/サービスを持つことができます。私はまだこれをチェックする機会があったhaventは

+0

これはいいアイデアです、ありがとうございます。おそらく、これはおそらく最も効率的で簡単です。しかし、できる限り一般的なままにしておきたいので、遠隔から任意のプロセスを開始することができます。 –

0

int型のpid =(INT)managementBaseObject [ "PROCESSID"];

プロセスremPrc = Process.GetProcessById(pid、RemoteMachine);

remPrc.WaitForExit();

+0

不運な作業Unfortunatley – Derek

関連する問題