Eli
Eli

Reputation: 4936

c#: WMI stop firing events

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?

Upvotes: 0

Views: 1201

Answers (1)

Alexandru
Alexandru

Reputation: 12912

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()

Upvotes: 0

Related Questions