Windows Management Instrumentation (WMI) can provide a wealth of information about various subsystems in Windows. Sometimes it’s the only (reasonable) way to get that information. Although I’ve known WMI for years, since it appeared in Windows 2000, I’ve recently was reminded of its power while preparing to deliver a Windows 7 course. To get a better understanding of WMI and how to use it in managed code to not only consume, but also to provide data and events, read Sasha Goldshtein’s article on CodeProject.
As a simple example, suppose we want to write a tool to monitor creation and destruction of processes. How would we go about doing it?
A naive approach might be to use polling by calling EnumProcesses (native) or Process.GetProcesses (managed) and manually looking for changes. This is clearly a waste of resources. What we want is some kind of event, to notify us of the creation or destruction of a process.
Curiously enough, the Win32 API does not offer any such function directly. It can be done in kernel mode (by writing a driver) using the function PsSetCreateProcessNotifyRoutine(Ex), but this seems too excessive – to write a driver just for this (seemingly) simple activity.
WMI offers a much easier solution. The System.Management namespace provides a relatively easy access to WMI data. The ManagementEventWatcher type provides a way to be notified when a WMI event is raised. Here’s a simple code that monitors creation and destruction of processes:
var watcher = new ManagementEventWatcher("SELECT * FROM Win32_ProcessStartTrace");
watcher.EventArrived += (o, e) => lstActivity.Items.Add(string.Format("Create:\t{0} (ID: {1})",
e.NewEvent["ProcessName"], e.NewEvent["ProcessId"]));
watcher.Start();
watcher = new ManagementEventWatcher("SELECT * FROM Win32_ProcessStopTrace");
watcher.EventArrived += (o, e) => lstActivity.Items.Add(string.Format("Destroy:\t{0} (ID: {1})",
e.NewEvent["ProcessName"], e.NewEvent["ProcessId"]));
watcher.Start();
The Attached ZIP contains a simple process watcher based on the previous code hosted in a WinForms application.
