مراقبة عملية WMI تستخدم الكثير من وحدة المعالجة المركزية!هل هناك طريقة أفضل؟

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

  •  19-08-2019
  •  | 
  •  

سؤال

أحتاج إلى مراقبة وقت بدء عمليات معينة أو إيقافها على جهاز يعمل بنظام Windows.أقوم حاليًا بالدخول إلى نظام WMI واستعلام عنه كل 5 ثوانٍ، ولكن هذا يتسبب في ارتفاع وحدة المعالجة المركزية كل 5 ثوانٍ لأن WMI هو WMI.هل هناك طريقة أفضل للقيام بذلك؟يمكنني فقط إنشاء قائمة بالعمليات الجارية وإرفاق حدث تم الخروج بها من خلال مساحة الاسم System.Diagnostics، ولكن لا يوجد معالج أحداث للإنشاء.

هل كانت مفيدة؟

المحلول

وهذا ليس بالضبط كيف كنت تفعل ذلك في العالم الحقيقي ولكن ينبغي أن تساعد. هذا لا يبدو أن حملة بلدي CPU كثيرا في كل شيء.

    static void Main(string[] args)
    {
        // Getting all instances of notepad
        // (this is only done once here so start up some notepad instances first)
        // you may want use GetProcessByPid or GetProcesses and filter them as required
        Process[] processesToWatch = Process.GetProcessesByName("notepad");

        foreach (var process in processesToWatch)
        {
            process.EnableRaisingEvents = true;
            process.Exited +=
                (s, e) => Console.WriteLine("An instance of notepad exited");
        }

        Thread watchThread = new Thread(() =>
            {
                while (true)
                {
                    Process[] processes = Process.GetProcesses();
                    foreach (var process in processes)
                    {
                        Console.WriteLine("{0}:{1}", process.Id, process.ProcessName);
                    }
                    // Don't dedicate a thread to this like I'm doing here
                    // setup a timer or something similiar
                    Thread.Sleep(2000);
                }
            });
        watchThread.IsBackground = true;
        watchThread.Start();

        Console.WriteLine("Polling processes and waiting for notepad process exit events");
        Console.ReadLine();
    }

نصائح أخرى

لقد واجهت ارتفاعات في وحدة المعالجة المركزية عند الاستماع إلى أحداث WMI في الحالات التي فشلت فيها في الانفصال بشكل صحيح عن الأحداث الخاصة بي عند الخروج/التنظيف.قد ترغب في التحقق من عدم "تسريب" اشتراكات أحداث WMI.فقط في حالة الانفصال عن الحدث في أقرب وقت ممكن وتأكد من القيام بذلك دائمًا.

ولتوضيح الأمر أكثر، إليك مثال من كتابي PowerShell يستمع إلى أحداث WMI باستخدام مكتبة PSEventing:

add -pssnapin pseventing -erroraction silallycontinue

$ QueryString = @'select * from __instancemodificationevent خلال 10 حيث targetinstance isa' win32_service 'و targetinstance.name =' w3svc 'و targetinstance.state =' stopped '' @ @

$ query = new -Object System.Management.wqleventquery `-ArgumentList $ QueryString

$ watcher = new-Object System.Management.ManagedeventWatcher ($ Query)

Connect-EventListener Watcher Eventarved

مراقب $.ابدأ()

صدى "في انتظار خدمة W3CSVC للتوقف ..." Get -Afent -Wait | foreach {كتابة -Foreground Red "توقفت خدمة W3SVC!" }

مراقب $.Stop()

وصل حدث مراقب قطع الاتصال-EventListener

صدى "تم"

إذا لم أفعل قطع الاتصال-EventListener عند الخروج من البرنامج النصي، أحصل على ارتفاعات في وحدة المعالجة المركزية (CPU) في المرة الثالثة أو الرابعة التي أرفق فيها الحدث.أعتقد أن النظام لا يزال يحاول تقديم الأحداث.

إذا كنت تبحث فقط عن PID/Name لعملياتك، فقد ترغب بدلاً من ذلك في التقاط أحداث Win32_ProcessTrace، باستخدام استعلام WQL مثل "SELECT * FROM Win32_ProcessTrace WHERE TargetInstance.ProcessName = 'name'" إذا كان قابلا للتطبيق*.

تكمن المشكلة في استخدام "SELECT * FROM __InstanceModificationEvent inside 10 WHERE TargetInstance ISA 'Win32Process' AND TargetInstance.Name = 'name'" في كيفية عمله على النهاية الخلفية.إذا قمت بفحص wbemess.log داخل الدليل %windir%\system32\wbem\logs، فستلاحظ السجلات التالية (باستخدام __InstanceDeletionEvent):

(Wed Jul 22 13:58:31 2009.73889577) : Registering notification sink with query select * from __InstanceDeletionEvent within 10 where TargetInstance ISA 'Win32_Process' in namespace //./root/CIMV2.
(Wed Jul 22 13:58:31 2009.73889577) : Activating filter 047209E0 with query select * from __InstanceDeletionEvent within 10 where TargetInstance ISA 'Win32_Process' in namespace //./root/CIMV2.
(Wed Jul 22 13:58:31 2009.73889577) : Activating filter 0225E560 with query select * from __ClassOperationEvent where TargetClass isa "Win32_Process" in namespace //./root/CIMV2.
(Wed Jul 22 13:58:31 2009.73889577) : Activating filter 'select * from __ClassOperationEvent where TargetClass isa "Win32_Process"' with provider $Core
(Wed Jul 22 13:58:31 2009.73889587) : Activating filter 'select * from __InstanceDeletionEvent within 10 where TargetInstance ISA 'Win32_Process'' with provider $Core
(Wed Jul 22 13:58:31 2009.73889587) : Instituting polling query select * from Win32_Process to satisfy event query select * from __InstanceDeletionEvent within 10 where TargetInstance ISA 'Win32_Process'
(Wed Jul 22 13:58:31 2009.73889587) : Executing polling query 'select * from Win32_Process' in namespace '//./root/CIMV2'
(Wed Jul 22 13:58:31 2009.73889697) : Polling query 'select * from Win32_Process' done
(Wed Jul 22 13:58:41 2009.73899702) : Executing polling query 'select * from Win32_Process' in namespace '//./root/CIMV2'
(Wed Jul 22 13:58:41 2009.73899792) : Polling query 'select * from Win32_Process' done

كما ترون، فإن تنفيذ الحدث الفعلي على الجهاز البعيد هو إجراء استعلام مقابل Win32_Process على فاصل زمني محدد بواسطة القيمة الخاصة بك في جملة YOUTHIN.ونتيجة لذلك، فإن أي عمليات تبدأ وتتوقف خلال هذا الاستقصاء لن تطلق أي حدث أبدًا.

يمكنك تعيين جملة YOUTHIN إلى قيمة صغيرة لمحاولة تقليل هذا التأثير، ولكن الحل الأفضل هو استخدام حدث حقيقي مثل Win32_ProcessTrace، والذي يجب أن يكون دائماً نار.

*لاحظ أن MSDN يشير إلى أن Win32_ProcessTrace يتطلب حدًا أدنى من نظام التشغيل Windows XP على جهاز عميل ونظام التشغيل Windows 2003 على جهاز خادم حتى يعمل.إذا كنت تعمل مع نظام تشغيل أقدم، فقد تكون عالقًا في استخدام استعلام __InstanceModificationEvent.

وجوابي هنا يذكر بديل آخر غير WMI: https://stackoverflow.com/a/50315772/3721646 يمكن الاستفسارات WMI تكلفة أداء وحدة المعالجة المركزية الثقيلة إذا لم تكن مصممة بشكل صحيح. إذا تم استخدام هذا الحدث لا يتجزأ من الطبقة Win32_Process لتتبع الحدث إنشاء العملية، أداء هذه الآثار بشكل كبير. نهج بديل هو للاستفادة من سجلات التدقيق الأمني. يمكنك تمكين تتبع عملية باستخدام نهج الأمان المحلي أو باستخدام GPO في حالة الآلات متعددة. بمجرد أن يبدأ تتبع العملية، يمكنك الاشتراك في سجلات الأحداث الأمنية مع استعلام XML مخصصة لمراقبة عمليات معينة من اهتمامك. معرف الحدث إنشاء العملية 4688. `

<QueryList>
 <Query Id="0" Path="Security">
   <Select Path="Security">
       *[EventData[Data[@Name='NewProcessName'] ='C:\Windows\explorer.exe']]
       and
       *[System[(EventID=4688)]]
   </Select>
 </Query>
</QueryList>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top