如何识别插入 USB 插槽的设备?

Posted

技术标签:

【中文标题】如何识别插入 USB 插槽的设备?【英文标题】:How to identify what device was plugged into the USB slot? 【发布时间】:2013-05-13 07:10:04 【问题描述】:

我想检测用户何时插入或移除 USB 声卡。当这种情况发生时,我已经设法实际捕捉到事件,但我不知道刚刚插入了什么。

我尝试了一种基于this问题的方法:

string query =
    "SELECT * FROM __InstanceCreationEvent " +
    "WITHIN 2 "
  + "WHERE TargetInstance ISA 'Win32_PnPEntity'";
var watcher = new ManagementEventWatcher(query);
watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
watcher.Start();

虽然我通过 EventArrived 事件获得通知,但我不知道如何确定刚刚插入的设备的实际名称。我已经检查了所有属性,但无法从中得出正面或反面.

我也尝试了不同的查询:

var query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent where EventType = 1 or EventType = 2");
var watcher = new ManagementEventWatcher(query);
watcher.EventArrived += watcher_EventArrived;
watcher.Stopped += watcher_Stopped;
watcher.Query = query;
watcher.Start();

但也无济于事。有没有办法找到插入或移除的设备的名称。

最重要的是,我想知道 USB 声卡何时插入或从系统中移除。它应该可以在 Windows 7 和 Vista 上运行(尽管我只会满足于 Win7)。

编辑:根据获奖提交者的建议,我创建了一个包含所有功能的 full solution。

【问题讨论】:

使用 RegisterDeviceNotification 事件怎么样?在这个库中使用例如:code.google.com/p/winusbnet @SimonMourier 这个库似乎更适合与 USB 设备通信而不是检测它们。我没有看到任何显示如何检测设备的示例,也没有看到 API 中有任何适合此目的的内容。 【参考方案1】:

编辑 1: 哦,原来它不是 USB 存储设备,而只是 USB 设备。我会寻找其他解决方案。


描述相同问题的两个链接:

http://hintdesk.com/c-catch-usb-plug-and-unplug-event/

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/37123526-83fa-4e96-a767-715fe225bf28/

if (e.NewEvent.ClassPath.ClassName == "__InstanceCreationEvent")

    Console.WriteLine("USB was plugged in");
    //Get disk letter
    foreach (ManagementObject partition in new ManagementObjectSearcher(
"ASSOCIATORS OF Win32_DiskDrive.DeviceID='" + mbo.Properties["DeviceID"].Value
+ "' WHERE AssocClass = Win32_DiskDriveToDiskPartition").Get())
    
        foreach (ManagementObject disk in new ManagementObjectSearcher(
                    "ASSOCIATORS OF Win32_DiskPartition.DeviceID='"
                        + partition["DeviceID"]
                        + "' WHERE AssocClass = Win32_LogicalDiskToPartition").Get())
        
            Console.WriteLine("Disk=" + disk["Name"]);
        
    

【讨论】:

【参考方案2】:

当我尝试@AngryHacker 解决方案时,我注意到DeviceChangedEventArgs 类从未被调用过。我删除了它,只是在watcher_eventArrived 方法中添加了Console.WriteLines()

除了删除DeviceChangedEventArgs,以下是我的改动:

 (at line 46 in EstablishedWatchEvents)
 // setup the query to monitor removal
const string qryRemoval = "SELECT *" +  "FROM __InstanceDeletionEvent "
             + "WITHIN 2 " + "WHERE TargetInstance ISA 'Win32_PnPEntity' ";

 #region Events

 private void insertWatcher_EventArrived(object sender, EventArrivedEventArgs e)
 

     var mbo = (ManagementBaseObject) e.NewEvent["TargetInstance"];
     if (new Guid((string) mbo["ClassGuid"]) == GUID_DEVCLASS_USB)
     
         var deviceName = (string) mbo["Name"];
         Console.WriteLine(deviceName + " was inserted");

     
 

 private void removeWatcher_EventArrived(object sender, EventArrivedEventArgs e)
 

     var mbo = (ManagementBaseObject)e.NewEvent["TargetInstance"];

     if (new Guid((string)mbo["ClassGuid"]) == GUID_DEVCLASS_USB)
     
         var deviceName = (string)mbo["Name"];
         Console.WriteLine(deviceName + " was removed");
     
 

 #endregion

【讨论】:

【参考方案3】:

如果我使用你的第一个代码,我可以这样定义我的事件:

    // define USB class guid (from devguid.h)
    static readonly Guid GUID_DEVCLASS_USB = new Guid("36fc9e60-c465-11cf-8056-444553540000");

    static void watcher_EventArrived(object sender, EventArrivedEventArgs e)
    
        ManagementBaseObject instance = (ManagementBaseObject )e.NewEvent["TargetInstance"];
        if (new Guid((string)instance["ClassGuid"]) == GUID_DEVCLASS_USB)
        
            // we're only interested by USB devices, dump all props
            foreach (var property in instance.Properties)
            
                Console.WriteLine(property.Name + " = " + property.Value);
            
        
    

这将转储如下内容:

Availability =
Caption = USB Mass Storage Device
ClassGuid = 36fc9e60-c465-11cf-8056-444553540000
CompatibleID = System.String[]
ConfigManagerErrorCode = 0
ConfigManagerUserConfig = False
CreationClassName = Win32_PnPEntity
Description = USB Mass Storage Device
DeviceID = USB\VID_18A5&PID_0243\07072BE66DD78609
ErrorCleared =
ErrorDescription =
HardwareID = System.String[]
InstallDate =
LastErrorCode =
Manufacturer = Compatible USB storage device
Name = USB Mass Storage Device
PNPDeviceID = USB\VID_18A5&PID_0243\07072BE66DD78609
PowerManagementCapabilities =
PowerManagementSupported =
Service = USBSTOR
Status = OK
StatusInfo =
SystemCreationClassName = Win32_ComputerSystem
SystemName = KILROY_WAS_HERE

这应该包含您需要的所有内容,包括您可以通过instance["DeviceID"] 之类的方式获得的设备 ID。

【讨论】:

deviceID 很好,但是如何获取实际设备的名称,例如Sennheiser USB headset. 您是否尝试过在没有我放在那里的 GUID_DEVCLASS_USB 检查的情况下运行该代码?它可以被识别为另一种类型(类别)的设备。例如,插入 USB 驱动器可能会引发许多事件(USB 设备、硬盘、音量等) 是的,我有,但我面临同样的问题:它给了我除了实际设备名称之外的所有内容。 我看到一个 JC Hutchins 的粉丝 :) 好的,我弄到一半了。我过滤了GUID_DEVCLASS_MEDIA (4D36E96C-E325-11CE-BFC1-08002BE10318) 而不是GUID_DEVCLASS_USB,这样就成功了。现在,唯一剩下的就是检测设备何时拔出。

以上是关于如何识别插入 USB 插槽的设备?的主要内容,如果未能解决你的问题,请参考以下文章

手机USB插入电脑后电脑无法识别

如何使用python检测USB设备是不是插入?

WMI:在插入时获取 USB 设备描述

usb slave 是啥?

电脑不识别U盘

如何在 Python 中侦听 Linux 中的“插入 USB 设备”事件?