【问题标题】:How to identify what device was plugged into the USB slot?如何识别插入 USB 插槽的设备?
【发布时间】: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 中有任何适合此目的的内容。

标签: c# usb wmi plug-and-play


【解决方案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,这样就成功了。现在,唯一剩下的就是检测设备何时拔出。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多