Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++ C# .NET Process XP WMI
Context:
I'm trying to get a notification whenever a process starts so I can do some logging. So, I set up my event handler like this:
 
Process Information and Notifications using WMI[^]
 
actually, more like this:
 
http://weblogs.asp.net/whaggard/archive/2006/02/11/438006.aspx[^]
 
Pretty standard stuff.
 
This is for Windows XP and Windows 2000
 
The problem: Basically, my event handler sometimes dies mid-execution. This seems to happen when the process its event is referring to exits quickly.
 
For example, my event handler will run properly when I run netstat, but not when I run 'netstat -ano', which usually exits more quickly. In the latter case, the event handler will print out some of its output, but not all.
 
Sometimes, in the latter case, it won't print out anything, so I don't know if I got an event notification at all.
 
I have not found any mention of this problem in cyberspace. Maybe someone with better google-fu or better terminology can point me in the right direction.
 
Getting events Synchronously:
 
http://msdn.microsoft.com/en-us/library/aa720671(v=vs.71).aspx[^]
 
So, if I loop watcher.WaitForNextEvent();, I'll often get no event for a quick-exiting process. If I run netstat, I'll get a response like half the time.
 
Things I've tried:
 
I've tried subscribing to Win32_ProcessStartTrace and __InstanceCreationEvent/__InstanceOperationEvent, but the behavior is more-or-less the same.
 
I've tried implementing this in C++, but I get pretty much the same behavior: http://msdn.microsoft.com/en-us/library/windows/desktop/aa390425(v=vs.85).aspx[^]
 
I've mitigated the problem by making the event handler start a thread, but sometimes the event handler is not alive long enough to create a new thread (with all the data I'll need about the specified process).
 
Messing with the "WITHIN 1" clause in the query seems to have no effect. Removing it causes an error.
 

 

 
Incidentally:
The event handlers for process termination have all the time in the world. No race condition there.
 
I need to look at everything a process writes to stdout.
 
So, I need notification when the process starts so I can grab all the output of this process...unless one of you knows how to get everything a process already wrote to stdout from an __InstanceDeletionEvent or a Win32_ProcessStopTrace;
 
Thank You!
using System;
using System.Management;
using System.Threading;
 
// This example shows synchronous consumption of events. The client 
// is blocked while waiting for events. See additional example for
// asynchronous event handling.

public class EventWatcherPolling
{
    public static int Main(string[] args)
    {
        // Create event query to be notified within 1 second of 
        // a change in a service
        WqlEventQuery query =
           new WqlEventQuery("__InstanceCreationEvent",
                           new TimeSpan(0, 0, 1),
                         "TargetInstance isa \"Win32_Process\"");
 
        // Initialize an event watcher and subscribe to events 
        // that match this query
        ManagementEventWatcher watcher = new ManagementEventWatcher(query);
 
        while (true)
        {
            try
            {
                Console.WriteLine("Waiting:");
                // Block until the next event occurs 
                // Note: this can be done in a loop if waiting for 
                //        more than one occurrence
                ManagementBaseObject e = watcher.WaitForNextEvent();
                
 
                //Display information from the event
                Console.WriteLine(
                   "IC: {0}",
                    ((ManagementBaseObject)e["TargetInstance"])["Name"]);
 
            }
            catch (Exception except)
            {
                Console.WriteLine("EXCEPTION: " + except.ToString());
            }
        }
 
        //Cancel the subscription
        watcher.Stop();
        return 0;
    }
}
Posted 2-Apr-13 11:29am
Edited 2-Apr-13 12:19pm
v3
Comments
Dave Kreskowiak at 2-Apr-13 16:56pm
   
Your event handler just doesn't die on its own. The code continues to run, but what may be causing your problem is that the object you're looking at may die because it's lifetime is controlled by another source.
 
Without seeing you actual handler code, it's impossible to say.
The_Inventor at 25-Aug-13 22:05pm
   
Maybe some kind of while loop, where you load data until the condition become true.
Member 2036792 at 2-Apr-13 17:02pm
   
THANK YOU FOR RESPONDING!
 
so, here's a simple synchronous example (just added a loop to this example: http://msdn.microsoft.com/en-us/library/aa720671(v=vs.71).aspx):
 
using System;
using System.Management;
using System.Threading;
 
// This example shows synchronous consumption of events. The client
// is blocked while waiting for events. See additional example for
// asynchronous event handling.
 
public class EventWatcherPolling
{
public static int Main(string[] args)
{
// Create event query to be notified within 1 second of
// a change in a service
WqlEventQuery query =
new WqlEventQuery("__InstanceCreationEvent",
new TimeSpan(0, 0, 1),
"TargetInstance isa \"Win32_Process\"");
 
// Initialize an event watcher and subscribe to events
// that match this query
ManagementEventWatcher watcher = new ManagementEventWatcher(query);
 
while (true)
{
try
{
Console.WriteLine("Waiting:");
// Block until the next event occurs
// Note: this can be done in a loop if waiting for
// more than one occurrence
ManagementBaseObject e = watcher.WaitForNextEvent();

 
//Display information from the event
Console.WriteLine(
"IC: {0}",
((ManagementBaseObject)e["TargetInstance"])["Name"]);
 
}
catch (Exception except)
{
Console.WriteLine("EXCEPTION: " + except.ToString());
}
}
 
//Cancel the subscription
watcher.Stop();
return 0;
}
}
 

If you run ipconfig or netstat or stuff that returns quickly, this thing will only pick up some of the events.
Member 2036792 at 2-Apr-13 17:31pm
   
You are right -- if I start my asynchronous handler like this:
 
static void startWatch_EventArrived(object sender, EventArrivedEventArgs e)
{
try
{
String name = (string)e.NewEvent.Properties["ProcessName"].Value;
Console.WriteLine("Process start handler {0}...", name);
Thread.Sleep(10000);
Console.WriteLine("...{0}", name);
...
 
It always makes it to the second console.writeline().
 
I'm the one who always kills my handler. That's very helpful! I wonder why my exception handler didn't tell me.
 
Anyway, this seems to have also solved my not-getting-any-event-at-all problem in the asynchronous example.
 
There still seems to be two problems.
 
1. The lingering race condition with resources: I still need to get some info from this event, and look up process info from it. Sometimes the process dies before I can do this. I could try to suspend the process -- but that would be a race condition, too.
 
2. synchronous example (my other comment post): I still have the not-getting-any-event-at-all problem in the synchronous example -- with quick-exiting processes.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 Maciej Los 295
1 OriginalGriff 249
2 Sergey Alexandrovich Kryukov 205
3 Aajmot Sk 197
4 Sinisa Hajnal 176
0 OriginalGriff 7,800
1 Sergey Alexandrovich Kryukov 7,072
2 DamithSL 5,604
3 Manas Bhardwaj 4,986
4 Maciej Los 4,790


Advertise | Privacy | Mobile
Web03 | 2.8.1411023.1 | Last Updated 2 Apr 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100