"Dilip" <rd*****@lycos.comwrote in message
news:a3**********************************@k13g2000 hse.googlegroups.com...
On Apr 11, 4:31 pm, "Willy Denoyette [MVP]"
<willy.denoye...@telenet.bewrote:
>"Dilip" <rdil...@lycos.comwrote in message
news:73**********************************@a23g200 0hsc.googlegroups.com...
Hi
I am using the following WMI code to watch for the termination of a
particular process. This code is running under Windows Vista.
public void WaitForDeath()
{
using (AutoResetEvent thisEvent = WatchForProcessDeath())
{
WaitHandle.WaitOne(thisEvent);
}
}
private AutoResetEvent WatchForProcessDeath()
{
AutoResetEvent evt = new AutoResetEvent(false);
string newQry =
"select * from __InstanceDeletionEvent within 2 where
TargetInstance ISA 'Win32_Process' and " +
"TargetInstance.Name = 'MyProcess.exe'";
ManagementEventWatcher mew = new ManagementEventWatcher(@"\\.\root
\CIMV2", newQry);
mew.EventArrived += delegate { evt.Set(); };
mew.Start();
return evt;
}
Our QA folks tested this functionality by calling WaitForDeath()
repeatedly in a tight loop. at some point, say after 3 hours or so,
we started getting a "Quota violation" exception of type
System.ManagementException on the Start() method of
ManagementEventWatcher.
I happened upon some posts related to this on the WMI newsgroup but I
am not clear how to solve this in my case.
1) Is this happening because of the query itself? If so, why does it
happen only after 3 hours and not right away?
2) Is this happening because I am not properly disposing of the
ManagementEventWatcher objects? In the EventArrived event I could
add:
mew.Stop();
mew.Dispose();
in addition to setting the autoreset event. I just don't know enough
about WMI to decide if it would help.
Can anyone help? (From past experience I really hope Mr. Willy
Denoyette sees this!)
You need to stop the ManagementEventWatcher when done with it. The Quota
limit for *all* events that get handled on a Completion Port thread is
1000
which equals the maximum number of CP threads per process in .NET.
Why it only happens after 3 hours depends on the frequency they called
the
method, call it in a tight loop and you won't have to wait longer than a
couple of seconds I guess.
Besides, it's preferable to use the Win32_ProcessStopTrace class on Vista
and higher, this class uses ETW which is really event driven while you
are
using a polling mechanism under the covers.
Willy.
Ok. It looks like all I have to do is replace my original
__InstanceDeletionEvent query with:
Select * from Win32_ProcessStopTrace where ProcessName='MyProcess.exe'
Am I right?
No, "select" for a trace events, you need to select the property of interest
in the eventhandler, something like:
using(ManagementEventWatcher w = new
ManagementEventWatcher("Win32_ProcessStopTrace"))
{
w.EventArrived += ProcessStopped;
w.Start();
Console.ReadLine(); // block main thread for test purposes
w.Stop();
}
}
static void ProcessStopped(object sender, EventArrivedEventArgs e) {
if((string)e.NewEvent.Properties["processname"].Value ==
"notepad.exe")
{
Console.WriteLine("Process: {0}, Stopped with Code: {1}",
(int)(uint)e.NewEvent.Properties["ProcessId"].Value,
(int)(uint)e.NewEvent.Properties["ExitStatus"].Value);
}
}
Willy.