2012-04-13 6 views
7

Я использую следующий код C# в службе Windows (который работает как NT_AUTHORITY\SYSTEM) для создания обработчика событий для получения событий создания процесса (с использованием WMI и WQL):Событие запуска процесса с использованием WMI - не все начатые процессы запуска обнаружены

string queryString = "SELECT * FROM Win32_ProcessStartTrace"; 
ManagementEventWatcher watcher = new ManagementEventWatcher(new WqlEventQuery(queryString)); 
watcher.EventArrived += new EventArrivedEventHandler(ProcessStartEvent); 
watcher.Start(); 

В ProcessStartEvent:

int processId = int.Parse(e.NewEvent.Properties["ProcessId"].Value.ToString()); 
Process proc = Process.GetProcessById(processId); 

Out("Received process: " + proc.ProcessName); 

проблема у меня в том, что (по какой-то странной причине) не каждый старт процесс с получил сообщение и сообщил о программе. Если я запускаю около 6 процессов одновременно, на выходе может не отображаться.

Я попытался провести некоторое исследование по созданию событий создания процесса с использованием WMI, но имеется ограниченная информация. Я видел, что это также возможно, чтобы захватить процесс начинает использовать что-то похожее на:

SELECT TargetInstance 
FROM __InstanceCreationEvent 
WITHIN 2 
WHERE TargetInstance ISA 'Win32_Process' 

(Как видно из this Stack Overflow answer)

Существуют ли какие-либо существенные различия между использованием __InstanceCreationEvent и Win32_ProcessStartTrace? Может ли это быть причиной моих проблем?

есть объяснение, почему я не получаю событие для начинается все процесса? Есть ли что-то более очевидное, что я здесь делаю неправильно?

+0

Возможный дубликат [.NET Events for Process executable start] (http://stackoverflow.com/questions/848618/net-events-for-process-executable-start) –

+0

@Dimi Я бы сказал, что это довольно другой вопрос, так как это фокусируется на том, почему некоторые события кажутся исчезающими, в то время как другие пойманы даже при использовании якобы «правильного» метода для обнаружения событий запуска процесса. – Xenon

ответ

6

Оба метода действительны, но работают по-разному.

Когда вы используете класс WMI __InstanceCreationEvent, вы используете событие intrinsic, что означает, что вы отслеживаете изменения в стандартной модели данных WMI (это работает как триггер в таблице).

Если вы используете Win32_ProcessStartTrace, вы используете событие Extrinsic, что означает, что вы используете специализированный класс событий, созданный для конкретной задачи, в этом случае контролируйте создание процесса.

Теперь вернемся к вашей проблеме, лучший способ избежать «потерянных» некоторых событий - создать permanent event consumer.

+0

Возможно ли создание постоянного потребителя событий с использованием C# /. NET? – Xenon

+0

стандарт использует mof, проверьте эту статью [Создание постоянных подписных сообщений WMI с помощью MOF] (http: //www.codeproject.com/Articles/28226/Create-WMI-Permanent-Event-Subscriptions-Using-M) – RRUZ

+0

Проблема с использованием MOF заключается в том, что мне нужно иметь возможность получать события в моем сервисном приложении C#. – Xenon

3

Я обнаружил, что когда вы получили событие, начатое процессом, передайте это событие в отдельный поток, например, для ускорения потока вы можете передать идентификатор процесса в новый поток.

Это означает, что WMI COM не попадает в путаницу и перестает работать.

см http://sourceforge.net/p/processhistory/code/HEAD/tree/trunk/PHLogger/COM_WMI_Consumer/

для некоторого рабочего кода C++.