我有一个需要安装的安装程序可执行文件。当我运行它时,它会启动一个msi来进行实际安装,然后立即死掉。这样做的副作用是它会将控制权返回给您在安装完成之前调用它的任何控制台。根据我运行它的机器,可能需要3到10分钟,因此调用脚本睡眠是不可取的。我会直接启动msi,但它抱怨缺少组件。

我有一个WSH脚本,它使用WMI启动一个进程,然后观察直到它的pid不再运行。有没有办法确定初始可执行文件正在执行的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

这可能是查找所需信息的一种方法。以下是在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