Basically, I want to time the run duration of an external process not triggered by my code. In order to achieve this, I am subscribing to the events of the specific process starting and ending, by the process name, using the following code (based on this answer):
private ManagementEventWatcher ProcessStartWatcher(string processName)
{
string queryString =
"SELECT TargetInstance" +
" FROM __InstanceCreationEvent " +
"WITHIN 1 " +
" 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 ProcessEndWatcher(string processName)
{
string queryString =
"SELECT TargetInstance" +
" FROM __InstanceDeletionEvent " +
"WITHIN 1 " +
" 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 ProcessStarted(object sender, EventArrivedEventArgs e)
{
this.processStart = DateTime.Now;
}
private void ProcessEnded(object sender, EventArrivedEventArgs e)
{
// use time recorded from ProcessStarted to calculate run duration, write to log file
this.logger.addRuntimeData((DateTime.Now - this.processStart).TotalSeconds);
}
The addRuntimeData(double seconds)
method is defined as:
public void addRuntimeData(double seconds)
{
this.runDurations.Add(seconds);
if (this.runDurations.Count > Properties.Settings.Default.MaxRunDurationData)
this.runDurations.RemoveAt(0);
this.updateLog();
}
public void updateLog()
{
this.logfileDirectory = Properties.Settings.Default.LogfileDirectory;
this.logfileFullPath = logfileDirectory + this.task.Name.toValidFilename() + this.logfileExtension;
Directory.CreateDirectory(logfileDirectory); // create directory if it does not already exist
this.toXElement().Save(this.logfileFullPath); // generate the XML and write it to the log file
}
Right now, I am just attempting to time a test process I wrote, and all the test process does is a single call to Console.WriteLine("Test process");
, so appropriate values for the recorded duration should roughly be in the range 0-2 seconds.
Sometimes, I get values that are appropriate, and sometimes I get values that are literally not possible to have been recorded, such as 63619141321.2978 seconds. This is equal to roughly 2017.3 years, which makes me think that it might have something to do with the start time being recorded as 01/01/0001 00:00:01
or something like that; is it possible that the issue has something to do with this?
If this is an issue that I can't help (like, for example, if it has something to do with how/when the OS triggers the messages), is there a way that I can filter out these obviously invalid data points?