使用WMI识别引起Win32_DeviceChangeEvent的设备 [英] Using WMI to identify which device caused a Win32_DeviceChangeEvent

查看:50
本文介绍了使用WMI识别引起Win32_DeviceChangeEvent的设备的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have been writing some code that detects add and removal of USB devices, and I've used the following WMI code to register for device change notifications:

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设备.我遇到的问题是,如何识别引起事件的设备?

This is great and all, it works for any USB device I plug in or remove from the system. The problem that I'm having is, how do I identify the the device specifically that caused the events?

在程序的其他地方,我保留了我最感兴趣的当前连接设备的列表,因此,如果发生设备删除事件,我可以使用"select * from Win32_PnPEntity"对照WMI检查该列表.或其他类似的查询.但是,这是识别被删除设备的非常不准确且繁琐的方式.附加的问题是,除非我提前缓存了Win32_PnPEntity的整个列表,并且确实进行了疯狂的比较/验证,否则我无法准确地知道添加了什么设备.

Elsewhere in my program, I'm keeping a list of currently connected devices that I'm most interested in, so if a device-removed event comes through, I can check that list against WMI using "select * from Win32_PnPEntity" or some other similar query. BUT, this is a very inaccurate and cumbersome way of identifying the device that was removed. The added problem is, I have no way of accurately telling what device was added, unless I cache the entire list of Win32_PnPEntity ahead of time, and do really crazy comparisons/validations.

我在这里缺少明显的东西吗?如何将设备更改事件关联到特定设备?

Am I missing something obvious here? How do I associate the device change events to a specific device?

更新:我仍然没有找到解决此问题的理想方法,但是我正在做的是在内存中维护一个当前连接的设备(我感兴趣的设备)列表,并且每次发生事件时处理(请参见上文)后,我查询Win32_PnPEntity以查看存储在已连接设备列表中的设备是否仍处于连接状态.这是次优的解决方案,因为似乎无法从指示设备更改事件"的事件中获取任何特定的设备标识信息,这很奇怪.似乎非常奇怪,该信息不可用.叹气

UPDATE: I still haven't come up with an ideal solution to this problem, but what I am doing is maintaining a list of currently connected devices (that I'm interested in) in memory, and every time an event is handled (see above), I query the Win32_PnPEntity to see if the devices I have stored in my connected device list are still connected. This is a sub-optimal solution, because it just seems weird that I can't get any specific device identification information from the event that indicates "device change event". Seems VERY strange, that this info is unavailable. sigh

推荐答案

好的,因此,在进行了进一步的研究和实验之后,我发现我需要使用其他WMI查询来解决我的问题,这就是将设备更改事件与特定设备相关联.在这种情况下,我需要找到WMI中通常被称为"TargetInstance"的内容.

Okay, so after some further investigation and experimenting, I've discovered that I need to use a different WMI query in order to solve my problem, which is to associate a device change event with a specific device. In this case, I need to find what seems to be conventionally referred to in WMI as "TargetInstance".

因此,我改用了以下WMI查询代码

So, I used the following WMI query code instead

            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子句)),瞧!我得到了创建的特定设备.

So the difference here is, that the __InstanceCreationEvent has a property called "TargetInstance", which is EXACTLY what I was looking for. I cast the TargetInstance property to a ManagementBaseObject (which is of type "Win32_PnPEntity" (per the ISA clause in the query above), and Voila! I get the specific device that was created.

对于我的原始查询"Select * from Win32_DeviceChangeEvent"如何对所有人都有用,仍然感到困惑,因为在触发通用事件通知后没有提供其他信息.无论哪种方式,此新查询都可以明显解决我的问题.WMI似乎很强大,但是找到要使用的正确查询可能很棘手,并且需要进行一些试验.

It still sort of baffles me as to how my original query "Select * from Win32_DeviceChangeEvent" would be useful to anyone at all, since there's no additional information provided after a generic event notification is fired. Either way, this new query a significantly cleaner solution to the my problem. WMI seems pretty powerful, but finding the correct query to use can be tricky, and requires some experimenting.

这篇关于使用WMI识别引起Win32_DeviceChangeEvent的设备的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆