質問

インストールする必要があるセットアップ実行可能ファイルがあります。実行すると、実際のインストールを行うために msi が起動され、すぐに終了します。この副作用として、インストールが完了する前に、呼び出し元のコンソールに制御が戻されることになります。実行するマシンによっては 3 ~ 10 分かかる場合があるため、呼び出しスクリプトをスリープ状態にすることは望ましくありません。msi を直接起動したいのですが、コンポーネントが不足しているというメッセージが表示されます。

WMI を使用してプロセスを開始し、プロセスの PID が実行されなくなるまで監視する WSH スクリプトがあります。最初の実行可能ファイルが実行している MSI の pid を特定し、WMI を使用してその pid が終了するのを監視する方法はありますか?起動プロセス情報はプロセスに関連付けられていますか?

役に立ちましたか?

解決

親プロセスとして初期設定が行われているプロセスの WMI ルックアップを実行するとうまくいきますか?たとえば、プロセス ID 4000 のコマンド プロンプトから MSI を起動した場合、次のコマンド ラインを実行して msiexec プロセスに関する情報を確認できます。

c:\>wmic PROCESS WHERE ParentProcessId=4000 GET CommandLine, ProcessId 
CommandLine                                                 ProcessId
"C:\Windows\System32\msiexec.exe" /i "C:\blahblahblah.msi"  2752

それが必要な情報を見つける方法の 1 つかもしれません。以下は、vbs でその情報を検索するデモです。

Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set colProcesses = objWMIService.ExecQuery("select * from Win32_Process where ParentProcessId = 4000")
For Each objProcess in colProcesses
    Wscript.Echo "Process ID: " & objProcess.ProcessId
Next

これがお役に立てば幸いです。

他のヒント

.NET 言語を使用している場合 (Win32 でも実行できますが、.NET の方がはるかに簡単です)、(Setup.exe への最初の呼び出しが完了した後) システム内のすべてのプロセスを列挙し、必要なすべてのプロセスを見つけることができます。親の PID が Setup.exe の PID に等しい - そして、それらすべてのプロセスを監視します。完了すると、セットアップは完了です。同様に、これ以上子プロセスを生成しないようにしてください。

これで済むはずです。

$p1 = [diagnostics.process]::start($pathToExecutable) # this way we know the PID of the initial exe
$p2 = get-wmiobject win32_process -filter "ParentProcessId = $($p1.Id)" # using Jim Olsen's tip
(get-process -id $p2.ProcessId).WaitForExit() # voila--no messy sleeping

残念ながら、.NET オブジェクトには ParentProcessId プロパティがなく、WMI オブジェクトには WaitForExit() メソッドがないため、行ったり来たりする必要があります。

Jeffrey Snover (いつも) への小道具 この記事.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top