I have some services that an application needs running in order for some of the app\'s features to work. I would like to enable the option to only start the external Window
Monitor if the process is running - one service must be running to do this though.
If you really don't want to consume any ressources - write a simple service in plain C. Service application written without MFC/ATL can consume as low as 300-400 kb memory and virutally no CPU cycles. When the process you are interested in starts you can spawn your C# services.
public Process IsProcessOpen(string name)
{
foreach (Process clsProcess in Process.GetProcesses())
if (clsProcess.ProcessName.Contains(name))
return clsProcess;
return null;
}
From this article, you can use WMI (the System.Management
namespace) in your service to watch for process start events.
void WaitForProcess()
{
ManagementEventWatcher startWatch = new ManagementEventWatcher(
new WqlEventQuery("SELECT * FROM Win32_ProcessStartTrace"));
startWatch.EventArrived
+= new EventArrivedEventHandler(startWatch_EventArrived);
startWatch.Start();
ManagementEventWatcher stopWatch = new ManagementEventWatcher(
new WqlEventQuery("SELECT * FROM Win32_ProcessStopTrace"));
stopWatch.EventArrived
+= new EventArrivedEventHandler(stopWatch_EventArrived);
stopWatch.Start();
}
static void stopWatch_EventArrived(object sender, EventArrivedEventArgs e) {
stopWatch.Stop();
Console.WriteLine("Process stopped: {0}"
, e.NewEvent.Properties["ProcessName"].Value);
}
static void startWatch_EventArrived(object sender, EventArrivedEventArgs e) {
startWatch.Stop();
Console.WriteLine("Process started: {0}"
, e.NewEvent.Properties["ProcessName"].Value);
}
}
WMI allows for fairly sophisticated queries; you can modify the queries here to trigger your event handler only when your watched app launches, or on other criteria. Here's a quick introduction, from a C# perspective.
In reply to the Windows 7 aspect of it not working. If you are monitoring 64 bit processes your process needs to be built to work in the 64bit address space too.
you have 3 options here:
The reliable/intrusive one, set up a hook in unmanaged code that communicates back to your C# app whenever an app is launched. This is hard to get right and involves loading an extra DLL with each process. (Alternatively you could set up a driver, which is even harder to write)
The less reliable way, list all the processes (using the System.Diagnostics.Process class) on a regular basis (say every 10-30 secs) to see if the app is launched.
It also may be possible to watch the Win32_Process, InstanceCreationEvent WMI event from managed code. Not sure how reliable this is, but I suspect it would be better than polling processes.