2008-12-05 7 views
2

Мне нужно посмотреть, когда определенные процессы запущены или остановлены на компьютере Windows. В настоящее время я использую систему WMI и запрашиваю ее каждые 5 секунд, но это вызывает всплеск процессора каждые 5 секунд, потому что WMI - это WMI. Есть ли лучший способ сделать это? Я мог бы просто составить список запущенных процессов и прикрепить к ним событие Exited, используя пространство имен System.Diagnostics, но для создания обработчика событий нет.WMI Process Watching использует слишком много CPU! Любой лучший метод?

ответ

1

Это не совсем так, как вы сделали бы это в реальном мире, но должны помочь. Похоже, что мой процессор вообще не сильно меняет.

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(); 
    } 
+0

Это маршрут, в который я попал, после того как я не смог получить WMI, чтобы быть приятнее для меня. – 2008-12-07 04:23:02

1

У меня были спайки CPU при прослушивании событий WMI в тех случаях, когда мне не удалось должным образом отделить от моих событий на выходе/очистки. Возможно, вы захотите проверить, что вы не «утечка» подписки на события WMI. На всякий случай отстранитесь от мероприятия как можно раньше и убедитесь, что вы всегда это делаете.

Для дополнительной иллюстрации, вот пример из my PowerShell book, что слушает события WMI с помощью библиотеки PSEventing:

Надстройка PSSnapin PSEventing -ErrorAction SilentlyContinue

$ QueryString = @ SELECT * FROM __InstanceModificationEvent WITHIN 10 WHERE TargetInstance ISA 'Win32_Service' И TargetInstance.Name = 'w3svc' И TargetInstance.State = 'Stopped' «@

$ запроса = System.Management.WQLEventQuery New-Object` -ArgumentList $ QueryString

$ наблюдатели = New-Object System.Management.ManagementEventWatcher ($ запрос)

Connect-EventListener Watcher EventArrived

$ watcher.Start()

эхо «Ожидая Служба W3CSVC , чтобы остановить ... "Get-Event -wait | foreach { Write-Host -foreground Red «Служба W3SVC прекратилась!» }

$ watcher.Stop()

Disconnect-EventListener наблюдающий EventArrived

эхо "сделано"

Если я не делаю Disconnect-EventListener бит на выходе скрипта , Я получаю всплески CPU в третий или четвертый раз, когда я присоединяюсь к событию. Я предполагаю, что система все еще пытается доставить события.

1

Если вы ищете только для PID/Название вашего процесса, вы можете вместо этого хотите, чтобы поднять на события Win32_ProcessTrace, используя запрос WQL, такие как «SELECT * FROM Win32_ProcessTrace WHERE TargetInstance.ProcessName =„имя“» если применимо *.

Ловушка использования «SELECT * FROM __InstanceModificationEvent WITHIN 10 WHERE TargetInstance ISA« Win32Process »AND TargetInstance.Name =« name »означает, что он работает на задней панели. Если вы проверяете wbemess.log в папке% WINDIR% \ system32 \ WBEM \ каталог журналов, можно заметить следующие журналы (используя __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 на интервале, который указан вашим значением в предложении WITHIN. В результате любые процессы, которые запускаются и останавливаются в этом опросе, никогда не будут запускать событие.

Вы можете установить предложение WITHIN на небольшое значение, чтобы попытаться свести к минимуму этот эффект, но лучшим решением является использование истинного события, такого как Win32_ProcessTrace, которое должно всегда пожара.

* Обратите внимание, что MSDN указывает, что для работы Win32_ProcessTrace требуется минимум Windows XP на клиентском компьютере и Windows 2003 на серверной машине. Если вы работаете с более старой ОС, вы можете застрять с помощью запроса __InstanceModificationEvent.

Смежные вопросы