Можно ли отслеживать процессы, которые запускает другой процесс через WMI?

StackOverflow https://stackoverflow.com/questions/106476

  •  01-07-2019
  •  | 
  •  

Вопрос

У меня есть установочный исполняемый файл, который мне нужно установить.Когда я запускаю его, он запускает msi для выполнения фактической установки, а затем немедленно умирает.Побочным эффектом этого является возврат управления обратно на любую консоль, с которой вы его вызываете, до завершения установки.В зависимости от того, на какой машине я его запускаю, это может занять от трех до десяти минут, поэтому перевод вызывающего скрипта в спящий режим нежелателен.Я бы запустил msi напрямую, но он жалуется на отсутствие компонентов.

У меня есть скрипт WSH, который использует WMI для запуска процесса, а затем следит, пока его pid больше не будет запущен.Есть ли какой-нибудь способ определить pid MSI, который выполняется исходным исполняемым файлом, а затем следить за завершением этого pid с помощью WMI?Связана ли вообще информация о процессе запуска с каким-либо процессом?

Это было полезно?

Решение

Поможет ли выполнение WMI-поиска процессов, которые имеют начальную настройку в качестве родительского процесса?Например, если я запускаю MSI из командной строки с идентификатором процесса 4000, я могу выполнить следующую командную строку, чтобы найти информацию о процессе 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 родительского элемента которых равен PID Setup.exe - и затем отслеживайте все эти процессы.Когда они завершатся - настройка завершена.Убедитесь, что они также больше не порождают дочерних процессов.

Это должно сработать.

$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(), поэтому нам приходится переходить туда и обратно.

Спасибо Джеффри Сноверу (всегда) за эта статья.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top