I'm using the Microsoft.Management.Infrastructure (1.0.0) package in a .Net Framework 4.7.2 application.
I'm using the CIM* classes to start a process on a remote machine and listen for when it finishes.
I've included powershell as a tag as this could be (and probably a lot more often is) done with powershell, so I didn't want to miss out on those expertise and wisdom.
For 4 out of 5 of the servers I'm doing this on, I have no issue and it works great. But for one of them the subscription to listen to the process exiting event, seems to not start firing for a good chunk of time (I'm talking minutes) and by this point the process I started and wanted to know had finished, had already finished and I'm left waiting for a process exit event that will never happen.
Anyway here is a small console app, that should allow you to do what I'm doing. Its pretty simple. I don't know if I'm doing something wrong (if so why does it work on the others) or if potentially the server configuration is causing issues or if its just a ' thats just how it is sometimes' scenario.
---- The Code -----
Required Nuget Package Microsoft.Management.Infrastructure 1.0.0
using System;
using System.Linq;
using System.Management;
using Microsoft.Management.Infrastructure;
namespace CimEventListener
{
class Program
{
static void Main(string[] args)
{
const string cimNmspc = @"root\cimv2";
Console.WriteLine("Enter Server Name to listen to");
var serverName = Console.ReadLine();
using (var session = CimSession.Create(serverName))
using (var observer = new CimObserver())
{
if (!TestConnection(session))
{
Console.Error.WriteLine($"Failed to create CimSession with machine: {serverName}");
Environment.Exit( -1);
}
observer.EventArrived += (s, res) =>
{
var exitingProcessId = (uint)res.Instance.CimInstanceProperties["ProcessId"].Value;
var exitingProcessName = $"{res.Instance.CimInstanceProperties["ProcessName"].Value}";
Console.WriteLine($"Process Exited - ID: {exitingProcessId} Name: {exitingProcessName}");
};
var wqlQuery = new WqlEventQuery("Win32_ProcessStopTrace"); //use this as it encapsulates the building of the query string
using (var processParams = new CimMethodParametersCollection())
using (session.SubscribeAsync(cimNmspc, wqlQuery.QueryLanguage, wqlQuery.QueryString).Subscribe(observer))
{
Console.WriteLine("Press Enter to stop listening");
Console.ReadLine();
}
}
Console.WriteLine("Complete");
}
// not strictly required but left it in as its useful for anyone running this
private static bool TestConnection(CimSession session)
{
if (!session.TestConnection(out var identityResp, out var cimException))
{
Console.Error.WriteLine($"Could not connect. Exception: {cimException}");
return false;
}
else
{
using (identityResp)
{
var details = string.Join(" | ", identityResp.CimInstanceProperties.Select(p => (p.Name, p.Value)));
Console.WriteLine($"Successfully Create CIM Session. Details: {details}");
return true;
}
}
}
}
// just a helper class
class CimObserver : IObserver<CimSubscriptionResult>, IDisposable
{
public event EventHandler<CimSubscriptionResult> EventArrived;
public event EventHandler Completed;
public void OnCompleted()
{
Completed?.Invoke(this, EventArgs.Empty);
}
public void OnError(Exception error) => throw error;
public void OnNext(CimSubscriptionResult value) => EventArrived?.Invoke(this, value);
public void Dispose()
{
EventArrived = null;
Completed = null;
}
}
}
I run this little console app against server x and almost immediately a see various background processes that are exiting coming through if I login to server x and start and kill note pad I see it
However server y - I see nothing at first and even if log on and start and stop a process, still nothing and then several minutes later, it starts giving me events.
Any ideas what could be causing this?