使用WMI识别导致Win32_DeviceChangeEvent的设备

时间:2011-03-11 22:01:13

标签: c# wmi

我一直在编写一些检测USB设备添加和删除的代码,我使用以下WMI代码注册设备更改通知:

watcher = new ManagementEventWatcher(query);
watcher.EventArrived += new EventArrivedEventHandler(DeviceChangeEventReceived);
watcher.Start();

这是处理程序代码:

void DeviceChangeEventReceived(object sender, EventArrivedEventArgs e)
{
   foreach (PropertyData pd in e.NewEvent.Properties)
   {
      Log.Debug("\t" + pd.Name + ":" + pd.Value + "\t" + pd.Value.GetType());
   }
}

这很棒,它适用于我插入或从系统中删除的任何USB设备。我遇到的问题是,如何识别导致事件的具体设备?

在我的程序的其他地方,我保留了我最感兴趣的当前连接设备列表,因此如果设备删除事件通过,我可以使用“select * from Win32_PnPEntity”检查该列表对WMI或其他一些类似的查询。但是,这是一种识别被移除设备的非常不准确且繁琐的方法。增加的问题是,除非我提前缓存整个Win32_PnPEntity列表,否则我无法准确地告知添加了什么设备,并且做了非常疯狂的比较/验证。

我错过了一些明显的东西吗?如何将设备更改事件与特定设备相关联?

更新:我还没有想出一个解决这个问题的理想方案,但我正在做的是在内存中维护一个当前连接的设备列表(我感兴趣),每次事件都是处理(见上文),我查询Win32_PnPEntity以查看我存储在连接设备列表中的设备是否仍然连接。这是次优解决方案,因为我无法从指示“设备更改事件”的事件中获取任何特定设备标识信息,这似乎很奇怪。看起来很奇怪,这个信息不可用。 叹息

1 个答案:

答案 0 :(得分:15)

好的,经过一些进一步的调查和实验,我发现我需要使用不同的WMI查询来解决我的问题,即将设备更改事件与特定设备相关联。在这种情况下,我需要找到WMI中传统上称为“TargetInstance”的内容。

所以,我使用了以下WMI查询代码

            ManagementEventWatcher watcher;
            string queryStr =
                "SELECT * FROM __InstanceCreationEvent " +
                "WITHIN 2 "
              + "WHERE TargetInstance ISA 'Win32_PnPEntity'"

            watcher = new ManagementEventWatcher(queryStr);
            watcher.EventArrived += new EventArrivedEventHandler(DeviceChangeEventReceived);
            watcher.Start();

所以区别在于,__ InstanceCreationEvent有一个名为“TargetInstance”的属性,这正是我所寻找的。我将TargetInstance属性转换为ManagementBaseObject(类型为“Win32_PnPEntity”(根据上面查询中的ISA子句)),并且Voila!我得到了创建的特定设备。

对于我的原始查询“Select * from Win32_DeviceChangeEvent”对任何人都有用,我仍然感到困惑,因为在触发通用事件通知后没有提供其他信息。无论哪种方式,这个新的查询是一个明显更清洁的解决我的问题。 WMI看起来非常强大,但找到正确的查询可能会很棘手,需要进行一些实验。