Is there any way to register for an event that fires when an executable of a particular filename starts? I know it's easy enough to get an event when a process exits, by getting the process handle and registering for the exited event. But how can you be notified when a process, that isn't already running, starts...without polling all the running processes?
You could use the following:
private ManagementEventWatcher WatchForProcessStart(string processName)
{
string queryString =
"SELECT TargetInstance" +
" FROM __InstanceCreationEvent " +
"WITHIN 10 " +
" WHERE TargetInstance ISA 'Win32_Process' " +
" AND TargetInstance.Name = '" + processName + "'";
// The dot in the scope means use the current machine
string scope = @"\\.\root\CIMV2";
// Create a watcher and listen for events
ManagementEventWatcher watcher = new ManagementEventWatcher(scope, queryString);
watcher.EventArrived += ProcessStarted;
watcher.Start();
return watcher;
}
private ManagementEventWatcher WatchForProcessEnd(string processName)
{
string queryString =
"SELECT TargetInstance" +
" FROM __InstanceDeletionEvent " +
"WITHIN 10 " +
" WHERE TargetInstance ISA 'Win32_Process' " +
" AND TargetInstance.Name = '" + processName + "'";
// The dot in the scope means use the current machine
string scope = @"\\.\root\CIMV2";
// Create a watcher and listen for events
ManagementEventWatcher watcher = new ManagementEventWatcher(scope, queryString);
watcher.EventArrived += ProcessEnded;
watcher.Start();
return watcher;
}
private void ProcessEnded(object sender, EventArrivedEventArgs e)
{
ManagementBaseObject targetInstance = (ManagementBaseObject) e.NewEvent.Properties["TargetInstance"].Value;
string processName = targetInstance.Properties["Name"].Value.ToString();
Console.WriteLine(String.Format("{0} process ended", processName));
}
private void ProcessStarted(object sender, EventArrivedEventArgs e)
{
ManagementBaseObject targetInstance = (ManagementBaseObject)e.NewEvent.Properties["TargetInstance"].Value;
string processName = targetInstance.Properties["Name"].Value.ToString();
Console.WriteLine(String.Format("{0} process started", processName));
}
You would then call either WatchForProcessStart and/or WatchForProcessEnd passing in your process name (eg "notepad.exe").
The ManagementEventWatcher object is returned from the two Watch* methods as it implements IDisposable and so you should call Dispose on these objects when you have finished with them to prevent issues.
You could also change the polling value in the queries if you need the event to be raised more quickly after the process has started. To do this change the line "WITHIN 10" to be WITHIN something less than 10.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With