8

I am using the following C# code in a Windows Service (which runs as NT_AUTHORITY\SYSTEM) to create an event handler for receiving process creation events (using WMI and WQL):

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

In ProcessStartEvent:

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

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

The problem I'm having is that (for some strange reason) not every process start is captured and reported by the program. If I start about 6 processes simultaneously, one may not show up in the output.

I've tried to do some research on capturing process creation events using WMI, but there is limited information available. I've seen that it is also possible to capture process starts using something similar to:

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

(As seen in this Stack Overflow answer)

Are there any major differences between using __InstanceCreationEvent and Win32_ProcessStartTrace? Could this be the cause of my problems?

Is there an explanation as to why I'm not receiving events for all process starts? Is there something more obvious that I'm doing wrong here?

Community
  • 1
  • 1
Xenon
  • 3,174
  • 18
  • 37
  • Possible duplicate of [.NET Events for Process executable start](http://stackoverflow.com/questions/848618/net-events-for-process-executable-start) – NoWar Jun 06 '16 at 17:26
  • @Dimi I would say this is quite a different question, since this focuses on why some events seemingly vanish while others are caught even when using the supposedly "correct" method for catching process start events. – Xenon Jun 16 '16 at 01:27
  • Late to the part, but I'd like to add that those *extrinsic* events (`Win32_ProcessStartTrace`, `Win32_ProcessStopTrace`) requires administrator rights, while the same is not needed for the *intrinsic* ones (`__InstanceCreationEvent`, `__InstanceDeletionEvent`). You can try this from a Powershell console already – superjos Sep 24 '18 at 10:14

2 Answers2

8

Both methods are valid but works in differents ways.

When you uses the __InstanceCreationEvent WMI class you are using a intrinsic event which means which you are monitoring changes in the standard WMI data model (this works like a trigger in a table).

When you uses the Win32_ProcessStartTrace you are using a Extrinsic event that means you are using a specialized event class made for a specific task in this case monitor the process creation.

Now back to your issue, the best way to avoid the "lost" of some events is creating a permanent event consumer.

RRUZ
  • 134,889
  • 20
  • 356
  • 483
  • Is it possible to create a permanent event consumer using C#/.NET? – Xenon Apr 13 '12 at 20:18
  • the standard is using mof, check this article [Creating WMI Permanent Event Subscriptions Using MOF](http://www.codeproject.com/Articles/28226/Creating-WMI-Permanent-Event-Subscriptions-Using-M) – RRUZ Apr 13 '12 at 20:23
  • The problem with using MOF is that I need to be able to receive the events in my C# service app. – Xenon Apr 13 '12 at 20:32
  • That is not a problem, create the permanent event using mof and then consume using c#. – RRUZ Apr 13 '12 at 20:35
  • Why is it that a temporary event consumer will miss some events anyhow? Shouldn't all events that fire while the app is running be 'caught'? Before I go ahead and implement permanent event consumption, I want to be sure that I can't solve this problem some other way, still using a temporary event consumer. – Xenon Apr 13 '12 at 20:43
  • 3
    To answer why some events are lost, is necessary dig in the internals of the WMI, the WMI uses a internal buffer to hold the events some times that buffer is not large enough for the throughput of events. I have a lot of [experience](http://code.google.com/p/wmi-delphi-code-creator/) with the WMI and believe me there is not exist a short answer for this issue. If you want i can recommend you books to learn about the internal of the WMI. – RRUZ Apr 13 '12 at 20:53
  • @RRUZ is there a good example of "creating a permanent event using mof and then consume using c#" – user1438082 Dec 17 '13 at 21:18
  • 1
    @user1438082, I always I've used mof for create permanent events, for consume from .Net you must implement the [`IWbemUnboundObjectSink`](http://msdn.microsoft.com/en-us/library/aa392125%28v=vs.85%29.aspx) interface from C#, try the [msdn documentation](http://msdn.microsoft.com/en-us/library/aa393014%28VS.85%29.aspx) about this topic. – RRUZ Dec 17 '13 at 21:34
  • can i call MOF using c# ? - see my fresh question here http://stackoverflow.com/questions/20645455/create-permanent-wmi-event – user1438082 Dec 17 '13 at 21:54
  • Monitoring WMI object creations using `__InstanceCreationEvent` seems to be very CPU intensive, regardless of WHERE query and even if the WITHIN clause is set to a second. – Gareth Oakley Sep 16 '14 at 10:12
4

I've found when you get an event that a process has started - pass that event into a seperate thread with for instance boost thread you can pass the process ID to a new thread.

This means the WMI COM doesn't get in a tangle and stop itself working.

see http://sourceforge.net/p/processhistory/code/HEAD/tree/trunk/PHLogger/ and look for a revision with COM_WMI_Consumer/

for some working C++ code.

Jan S
  • 408
  • 6
  • 15