Cristi M
Cristi M

Reputation: 446

Asynchronous WMI Event handling in .NET

I am trying to run some processes remotely using WMI and the wait for the process to finish. Currently the event watcher is semi-synchronous using WaitForNextEvent which also has a timeout in case the something happens to the program. All this works well. I tried modifying this to asynchronous event handling but I get an Access Denied error when starting the event watcher. Now this would not be a big deal because I could stick with the semi-synchronous method, but there is one exception.

If, for some reason, during the execution of the program the machine restarts, freezes, or looses the network connection, the WaitForNextEvent does not throw a timeout exception, but blocks the thread indefinitely(I left it there for 10 minutes with no answer , timeout was 30 seconds). My question is: does anyone know if the event watcher can be set up in a specific way in order to timeout regardless of the connection, or to setup the client side in order to have access to asynchronous permissions. Normally, the first one would be preferred, but the second one is also an option.

ManagementEventWatcher w = new ManagementEventWatcher(managementScope,
    new WqlEventQuery(
        "select * from Win32_ProcessStopTrace where ProcessId=" + ProcessId));

w.Options.Timeout = new TimeSpan(0, 0, 0, 30);

var ev = w.WaitForNextEvent();

I would like to know if ManagementeventWatcher has some options to return or timeout regardless of the connection, or if an asynchronous method can be used in order to capture events.

Solution

ManagementEventWatcher w = new ManagementEventWatcher(managementScope,
    new WqlEventQuery(
        "select * from Win32_ProcessStopTrace where ProcessId=" + ProcessId));

w.Options.Timeout = new TimeSpan(0, 0, 0, 0, 1);
DateTime start = DateTime.Now;
while (Status == StatusNotStarted) //default status(just strings)
{
    try
    {
        var ev = w.WaitForNextEvent();
        ReturnCode = (uint)ev.Properties["ExitStatus"].Value;
        Status = (ReturnCode == 0) ? StatusOk : StatusFailed;
    }
    catch (ManagementException ex)
    {
        if (!ex.Message.Contains("Timed out"))
        {
            throw ex;
        }
        try
        {
            Ping p = new Ping();
            PingReply reply = p.Send(MachineIP);
            if (reply.Status != IPStatus.Success)
            {
                Status = StatusFailed;
            }
            else
            {
                DateTime end = DateTime.Now;
                TimeSpan duration = end - start;
                if (duration.TotalMilliseconds > Timeout)
                {
                    Status = StatusFailed;
                }
            }
        }
    }
}

Upvotes: 4

Views: 2414

Answers (1)

Sebastian Meier
Sebastian Meier

Reputation: 75

This answer describes a way of implementing a non-blocking WaitForNextEvent()

https://social.msdn.microsoft.com/Forums/vstudio/en-US/c2b6a2f4-eb84-4bbb-acdb-bbef4b0611e6/nonblocking-managementeventwatcherwaitfornextevent?forum=csharpgeneral

Hope this helps

Upvotes: 0

Related Questions