一次只有一个 ManagementEventWatcher 进程监听事件

问题描述 投票:0回答:1

我编写了一个 C# 程序,用于读取特定命名空间中的 WMI 实例操作事件。另一个第三方软件(SCCM 客户端 [1])负责在后台创建这些实例。当运行我的程序的多个实例时,只有第一个实例能够侦听事件并触发回调函数。其余进程继续循环,而不在控制台上记录任何内容。此外,如果我终止第一个进程并生成一个新进程,则所有进程(已运行的进程或新进程)仍然无法读取新的实例操作事件,即使它们在 WMI Explorer 工具中可见。是什么阻止其他进程也监听这些事件?

class Program
{

    static ManagementEventWatcher watcher;


    static void StopListening(object sender, ConsoleCancelEventArgs e)
    {

        Console.WriteLine("Stopping listener");
        watcher.Stop();
        watcher.Dispose();

        watcher.EventArrived -= WmiEventArrived;
        
        Console.WriteLine("...stopped.");

    }

    static void Main(string[] args)
    {
        string ClassName = "CCM_StateMsg";
        string WmiQueryAsync = "SELECT * FROM __InstanceOperationEvent WHERE TargetInstance ISA '{0}'";
        string query = string.Format(CultureInfo.InvariantCulture, WmiQueryAsync, ClassName);

        string scope = @"root\ccm\StateMsg";

        watcher = new ManagementEventWatcher(scope, query);
        watcher.EventArrived += WmiEventArrived;

        Console.CancelKeyPress += StopListening;

        Console.WriteLine("Starting watcher");
        watcher.Start();
        Console.WriteLine("...started");

        while (true)
        {
            Console.WriteLine("Waiting for events...");
            Thread.Sleep(10000);
        }
    }

    public static void WmiEventArrived(object sender, EventArrivedEventArgs e)
    {

        // Choose type of event based on class name
        string eventClassName = (string)e.NewEvent.GetPropertyValue("__CLASS");

        Console.WriteLine("StateMessageProvider got event from WMI of type: {0}", eventClassName);

        ManagementBaseObject currInstance = (ManagementBaseObject)e.NewEvent.GetPropertyValue("TargetInstance");
        // RAISE THE EVENT            
        Console.WriteLine("GOT EVENT: {0}", e.NewEvent.ClassPath.ToString());

    }
}

}

[1] https://learn.microsoft.com/en-us/mem/configmgr/develop/core/understand/sqlviews/wmi-namespaces-classes-configuration-manager-reports

c# windows wmi system.management managementeventwatcher
1个回答
0
投票

您的第一个程序只能侦听 WMI 事件而后续实例都无法接收事件的问题可能与 ManagementEventWatcher 类的功能有关。此类的结构对于给定查询一次仅允许一个订阅。

你可以尝试一下吗?

 static void Main(string[] args) {
    string ClassName = "CCM_StateMsg";
    string WmiQueryAsync = "SELECT * FROM __InstanceOperationEvent WHERE TargetInstance ISA '{0}' AND SourceInstanceName='{1}'";
    
    // Generate a unique identifier for this instance
    string instanceId = Guid.NewGuid().ToString();

    string query = string.Format(WmiQueryAsync, ClassName, instanceId);
    string scope = @"root\ccm\StateMsg";

    watcher = new ManagementEventWatcher(scope, query);
    watcher.EventArrived += (sender, e) => WmiEventArrived(sender, e, instanceId);

}

public static void WmiEventArrived(object sender, EventArrivedEventArgs e, string instanceId)
{
    string eventInstanceId = (string)e.NewEvent.GetPropertyValue("SourceInstanceName");

    if (eventInstanceId != instanceId)
    {
        // Ignore events not intended for this instance
        return;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.