Search code examples
c#asynchronouswmiremote-server

Asynchronous Remote WMI Calls C#


I'm really struggling to get WMI data from a remote host in an asynchronous way. After a lot of research, I can't find any clear examples, Microsoft's documentation only has VB and C++ code and there are even articles explaining why it's a bad idea. I've come from PowerShell, with that I would just create a new runspace to get the information.

I currently have a WPF window that I want to remain responsive whilst querying the information before updating the window. I've currently only managed to use synchronous calls using CimSession.Create and QueryInstance.

I would really appreciate some help with this :)


Solution

  • After proposing the same question to the MSDN forums, I got the correct answer and thought I would share it here as well :) I have put comments into the code to explain what is happening:

    //Used to define what is returned in the async results
    public static CimAsyncMultipleResults<CimInstance> GetValues(CimSession _session)
    {
        return _session.QueryInstancesAsync(@"root\cimv2", "WQL", "SELECT Username FROM Win32_ComputerSystem");
    }
    
    //This watches the async progress
    class CimInstanceWatcher : IObserver<CimInstance>
    {
        public void OnCompleted()
        {
            Console.WriteLine("Done");
        }
    
        public void OnError(Exception e)
        {
            Console.WriteLine("Error: " + e.Message);
        }
    
        public void OnNext (CimInstance value)
        {
            Console.WriteLine("Value: " + value);
        }
    }
    
    private static void Main()
    {
        //Leaving cimsession creation as sync because is happens "instantly"
        CimSession Session = CimSession.Create("PC-NAME");
        //Creating a new watcher object
        var instanceObject = new CimInstanceWatcher();
        //Subscribing the watcher object to the async call
        GetValues(Session).Subscribe(instanceObject);
        Console.ReadLine();
    }