I am writing a program that must register time of starting a process such as notepad. I thought that it is good to create a Timer that checks all of processes every second. But I think that it will slow down the user's computer. Is there a better way of doing this?
Initially determine for all running processes the creation time. Then use WMI to register for process creation events.
See the code below for a small example on how to use WMI for process creation events:
static void Main(string[] args)
{
using (ManagementEventWatcher eventWatcher =
new ManagementEventWatcher(@"SELECT * FROM
__InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Process'"))
{
// Subscribe for process creation notification.
eventWatcher.EventArrived += ProcessStarted_EventArrived;
eventWatcher.Start();
Console.In.ReadLine();
eventWatcher.EventArrived -= ProcessStarted_EventArrived;
eventWatcher.Stop();
}
}
static void ProcessStarted_EventArrived(object sender, EventArrivedEventArgs e)
{
ManagementBaseObject obj = e.NewEvent["TargetInstance"] as ManagementBaseObject;
// The Win32_Process class also contains a CreationDate property.
Console.Out.WriteLine("ProcessName: {0} " + obj.Properties["Name"].Value);
}
BEGIN EDIT:
I've further investigated process creation detection with WMI and there is a (more) resouces friendly solution (but needs administrative privileges) using the Win32_ProcessStartTrace
class (please see TECHNET for further information):
using (ManagementEventWatcher eventWatcher =
new ManagementEventWatcher(@"SELECT * FROM Win32_ProcessStartTrace"))
{
// Subscribe for process creation notification.
eventWatcher.EventArrived += ProcessStarted_EventArrived;
eventWatcher.Start();
Console.Out.WriteLine("started");
Console.In.ReadLine();
eventWatcher.EventArrived -= ProcessStarted_EventArrived;
eventWatcher.Stop();
}
static void ProcessStarted_EventArrived(object sender, EventArrivedEventArgs e)
{
Console.Out.WriteLine("ProcessName: {0} "
+ e.NewEvent.Properties["ProcessName"].Value);
}
In this solution you do not have to set an polling interval.
END EDIT
BEGIN EDIT 2:
You could use the Win32_ProcessStopTrace
class to monitor process stop events. To combine both process start and process stop events use the Win32_ProcessTrace
class. In the event handler use the ClassPath
proberty to distinguish between start/stop events:
using (ManagementEventWatcher eventWatcher =
new ManagementEventWatcher(@"SELECT * FROM Win32_ProcessTrace"))
{
eventWatcher.EventArrived += Process_EventArrived;
eventWatcher.Start();
Console.Out.WriteLine("started");
Console.In.ReadLine();
eventWatcher.EventArrived -= Process_EventArrived;
eventWatcher.Stop();
}
static void Process_EventArrived(object sender, EventArrivedEventArgs e)
{
Console.Out.WriteLine(e.NewEvent.ClassPath); // Use class path to distinguish
// between start/stop process events.
Console.Out.WriteLine("ProcessName: {0} "
+ e.NewEvent.Properties["ProcessName"].Value);
}
END EDIT 2
There is no need to monitor anything at all. All you need to do is to enumerate your processes and fetch from the Process Instances StartTime.
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