0

I'm using WMI to monitor start and stop processes on Win XP machine

My code goes like this:

ManagementEventWatcher m_Create;
ManagementEventWatcher m_Delete;

private void SetMonitors()
{
    string queryStartTrace = "SELECT * FROM Win32_ProcessStartTrace";
    string queryStopTrace = "SELECT * FROM Win32_ProcessStopTrace";

    m_Create = new ManagementEventWatcher(queryStartTrace);
    m_Delete = new ManagementEventWatcher(queryStopTrace);

    m_Create.EventArrived += new EventArrivedEventHandler(this.OnCreationArrived_Event);
    m_Delete.EventArrived += new EventArrivedEventHandler(this.OnDeletionArrived_Event);
}

private void OnCreationArrived_Event(object sender, EventArrivedEventArgs e){...}

private void OnDeletionArrived_Event(object sender, EventArrivedEventArgs e){...}

Everything works fine. But suddenly it stops working, don't know why. Only after restart my machine it returns to work.

Edit 1 As @Alexandru helped me, I assigned the watchers to stopped and disposed events:

m_Create.Stopped += new StoppedEventHandler(watcherCreate_Stopped);
m_Create.Disposed += new EventHandler(watcherCreate_Disposed);

m_Delete.Stopped += new StoppedEventHandler(watcherDelete_Stopped);
m_Delete.Disposed += new EventHandler(watcherDelete_Disposed);

And added those methods:

void watcherCreate_Stopped(object sender, StoppedEventArgs e)
{
    if (m_activeWatchers)
        m_watcherCreate.Start();
}

void watcherCreate_Disposed(object sender, EventArgs e)
{
    if (m_activeWatchers)
        m_watcherCreate.Start();
}

void watcherDelete_Disposed(object sender, EventArgs e)
{
    if (m_activeWatchers)
        m_watcherDelete.Start();
}

void watcherDelete_Stopped(object sender, StoppedEventArgs e)
{
    if (m_activeWatchers)
        m_watcherDelete.Start();
}

Now I'm dealing with an interesting problem, the stopped event fired -> and then there is there are the calls m_Create.Start(), m_Delete.Start() and then stopped event fired -> and so on until full quota...

Edit 2 Found this link ManagementEventWatcher stops raising EventArrived. with no helpful answer but with some hint- Should I unregister WMI events when my program closes?

Any help?

Eli
  • 4,576
  • 1
  • 27
  • 39
  • It may help to check two more events on each of your ManagementEventWatcher objects: Stopped and Disposed. Do these ever get called? – Alexandru Nov 24 '14 at 15:47
  • @Alexandru What do you mean? How the query should look like? – Eli Nov 24 '14 at 15:53
  • You subsrcibed to the EventArrived events in your code. Do the same thing for the Stopped and Disposed events and see if they get called at some point. – Alexandru Nov 24 '14 at 15:59
  • Got it. Do you thing I can miss stopped processes if I won't subsrcibe to Stopped and Disposed? – Eli Nov 24 '14 at 16:04
  • Sorry. Now I understood what you mean. So, those events are fired when something occurred to the watcher.. – Eli Nov 24 '14 at 16:09
  • Now we just need to wait for it to stop firing events - it can happen at any time... so thanks for now. I'll come back when it will occurred. – Eli Nov 24 '14 at 16:16
  • Yes. Something like `m_Create.Stopped += new ...` and `m_Delete.Stopped += new ...` should tell you if the watcher has stopped watching for events. – Alexandru Nov 24 '14 at 16:20
  • OK. So what should I do when it fires? m_Create.Start()? – Eli Nov 24 '14 at 16:38
  • I think that might work. Try it out and see if that works for your situation :) Coding is all about testing. – Alexandru Nov 24 '14 at 16:41
  • Yes well my problem is not deterministic so.. we will just wait and see :) Thanks a lot! I have been reading your post, you’re awesome! – Eli Nov 24 '14 at 16:47
  • You're awesome too. Don't stop coding :) – Alexandru Nov 24 '14 at 17:04
  • I think you should use separate events for m_Create and m_Delete. If one stops, you should not have to restart both. I read your edit but I'm not sure I fully understand the problem. Does it just keep looping? – Alexandru Nov 27 '14 at 14:38
  • @Alexandru you right. I will separate them. Yes it seem not to be able to re-start and raise that event again and again.. – Eli Nov 27 '14 at 14:59
  • I found this link that may be can give a clue: https://social.msdn.microsoft.com/Forums/vstudio/en-US/ed03e8ad-28c3-4cf4-ae06-fe8f27adac2f/managementeventwatcher-stops-raising-eventarrived-after-running-application-several-times?forum=netfxbcl Maybe I missed here something: should I un-register WMI events when my program closes? – Eli Nov 27 '14 at 15:32
  • I'll write you an answer, hopefully it helps in your case. – Alexandru Nov 27 '14 at 16:22

1 Answers1

0

Try this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Text;
using System.Threading.Tasks;

namespace EventWatcher
{
    class Program
    {
        static void Main(string[] args)
        {
            StartMonitoringProcessCreation();
            StartMonitoringProcessTermination();
            Console.ReadLine();
        }

        private static void StartMonitoringProcessCreation()
        {
            ManagementEventWatcher startWatcher = new ManagementEventWatcher("SELECT * FROM Win32_ProcessStartTrace");
            startWatcher.EventArrived += new EventArrivedEventHandler(startWatcher_EventArrived);
            startWatcher.Stopped += new StoppedEventHandler(startWatcher_Stopped);
            startWatcher.Disposed += new EventHandler(startWatcher_Disposed);
            startWatcher.Start();
        }

        private static void StartMonitoringProcessTermination()
        {
            ManagementEventWatcher stopWatcher = new ManagementEventWatcher("SELECT * FROM Win32_ProcessStopTrace");
            stopWatcher.EventArrived += new EventArrivedEventHandler(stopWatcher_EventArrived);
            stopWatcher.Stopped += new StoppedEventHandler(stopWatcher_Stopped);
            stopWatcher.Disposed += new EventHandler(stopWatcher_Disposed);
            stopWatcher.Start();
        }

        static void startWatcher_EventArrived(object sender, EventArrivedEventArgs e)
        {
            Console.WriteLine("Got creation event.");
        }

        static void startWatcher_Stopped(object sender, StoppedEventArgs e)
        {
            Console.WriteLine("The startWatcher has stopped. Disposing it.");
            ((ManagementEventWatcher)sender).Dispose();
        }

        static void startWatcher_Disposed(object sender, EventArgs e)
        {
            Console.WriteLine("The startWatcher has been disposed. Restarting it.");
            StartMonitoringProcessCreation();
        }

        static void stopWatcher_EventArrived(object sender, EventArrivedEventArgs e)
        {
            Console.WriteLine("Got termination event.");
        }

        static void stopWatcher_Stopped(object sender, StoppedEventArgs e)
        {
            Console.WriteLine("The stopWatcher has stopped. Disposing it.");
            ((ManagementEventWatcher)sender).Dispose();
        }

        static void stopWatcher_Disposed(object sender, EventArgs e)
        {
            Console.WriteLine("The stopWatcher has been disposed. Restarting it.");
            StartMonitoringProcessTermination();
        }
    }
}

Edit: Because of what you've told me, it may just be easier for you to do something like this...

new Thread(() =>
{
    while (true)
    {
        Process[] list = Process.GetProcessesByName("yourProcessName");
        if (list.Length == 0)
            Console.WriteLine("Not running.");
        else
            Console.WriteLine("Running.");
        Thread.Sleep(1000);
    }
}).Start()
Alexandru
  • 12,264
  • 17
  • 113
  • 208
  • Hi Alexandru, sorry for the weekend delay :) I'll check your answer, many thanks! – Eli Nov 30 '14 at 08:07
  • Hi, I have tried it, unfortunately it start to escalate soon as I implement it - its enter to infinite loop. But I tried something else, just call to `((ManagementEventWatcher)sender).Start();` instead of dispose at stopped event. Actually I'm still not sure its OK, I need more testing on it. – Eli Nov 30 '14 at 15:13
  • @Eli That sounds strange. The code works on my machine, but it seems Stop is always getting called on yours. For example, at the moment you start it, it sounds like it is stopping instantly. Try putting a breakpoint on stop and see how soon it comes up. – Alexandru Nov 30 '14 at 15:56
  • @Eli Why are you monitoring processes, in particular? Maybe there is a better way of achieving your goal. If you tell me, I might be able to point you towards a better solution. – Alexandru Dec 01 '14 at 20:43
  • All I need to know is which and when process starts/stopped. Sometimes I'll stop it myself and start it again afterwords. The thing is it can be stop by it's own and it's very not deterministic so it's vary hard to define how and when or why doe's it happen. – Eli Dec 02 '14 at 10:31
  • Is there a need to dispose wmi watchers when I'm closing my program? – Eli Dec 02 '14 at 10:32
  • 1
    @Eli No need to dispose when closing the program, as it will dispose it on its own. But, you should look at this: http://stackoverflow.com/questions/262280/how-can-i-know-if-a-process-is-running. It might just be a lot easier for you to call `Process.GetProcessesByName("yourProcessName");` in a thread, over and over, and monitor it that way. I'll edit my question and show you. – Alexandru Dec 02 '14 at 14:14
  • Thank for knowledge me about the dispose - I was a bit worry because I'm already assumed its managed..:). Unfortunately your edit doesn't help me. I don't know for which process I'm waiting for because I need to catch them all - no matter what no matter when. I'm also prefer to avoid from polling so `GetAllProcesses` wont help me either. – Eli Dec 02 '14 at 15:49