هل من الممكن مراقبة العمليات التي يتم إطلاقها عبر عملية أخرى عبر WMI؟
سؤال
لدي إعداد قابل للتنفيذ وأحتاج إلى تثبيته.عندما أقوم بتشغيله، يقوم بتشغيل 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()، لذا يتعين علينا الرجوع ذهابًا وإيابًا.
الدعائم لجيفري سنوفر (دائمًا) لـ هذا المقال.