【问题标题】:Possible to monitor processes another process launches via WMI?可以通过 WMI 监视另一个进程启动的进程吗?
【发布时间】:2010-09-11 12:17:15
【问题描述】:
我有一个需要安装的安装程序可执行文件。当我运行它时,它会启动一个 msi 来进行实际安装,然后立即死亡。这样做的副作用是它将控制权返回给您在安装完成之前调用它的任何控制台。根据我在哪台机器上运行它,它可能需要三到十分钟,因此不希望调用脚本休眠。我会直接启动 msi,但它抱怨缺少组件。
我有一个 WSH 脚本,它使用 WMI 启动一个进程,然后观察它,直到它的 pid 不再运行。有没有办法确定初始可执行文件正在执行的 MSI 的 pid,然后使用 WMI 观察该 pid 结束?启动进程信息是否与进程相关联?
【问题讨论】:
标签:
windows
scripting
wmi
wsh
【解决方案1】:
将初始设置为父进程的进程进行 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
这可能是查找所需信息的一种方式。这是在 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
我希望这会有所帮助。
【解决方案2】:
如果您使用的是 .NET 语言(您可以在 Win32 中执行此操作,但在 .NET 中更容易),您可以枚举系统中的所有进程(在您对 Setup.exe 的初始调用完成后)并找到所有父进程的 PID 等于 Setup.exe 的 PID 的进程 - 然后监视所有这些进程。他们何时完成 - 设置完成。确保它们也不再产生任何子进程。
【解决方案3】:
应该这样做。
$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() 方法,所以我们不得不来回折腾。
为this article 向 Jeffrey Snover(总是)提供支持。