Получить список подключенных USB-устройств



Как я могу получить список всех подключенных USB-устройств на компьютере с Windows?

709   7  

7 ответов:

добавить ссылку на System.Управления для вашего проекта, а затем попробуйте что-то вроде этого:

namespace ConsoleApplication1
{
  using System;
  using System.Collections.Generic;
  using System.Management; // need to add System.Management to your project references.

  class Program
  {
    static void Main(string[] args)
    {
      var usbDevices = GetUSBDevices();

      foreach (var usbDevice in usbDevices)
      {
        Console.WriteLine("Device ID: {0}, PNP Device ID: {1}, Description: {2}",
            usbDevice.DeviceID, usbDevice.PnpDeviceID, usbDevice.Description);
      }

      Console.Read();
    }

    static List<USBDeviceInfo> GetUSBDevices()
    {
      List<USBDeviceInfo> devices = new List<USBDeviceInfo>();

      ManagementObjectCollection collection;
      using (var searcher = new ManagementObjectSearcher(@"Select * From Win32_USBHub"))
        collection = searcher.Get();      

      foreach (var device in collection)
      {
        devices.Add(new USBDeviceInfo(
        (string)device.GetPropertyValue("DeviceID"),
        (string)device.GetPropertyValue("PNPDeviceID"),
        (string)device.GetPropertyValue("Description")
        ));
      }

      collection.Dispose();
      return devices;
    }
  }

  class USBDeviceInfo
  {
    public USBDeviceInfo(string deviceID, string pnpDeviceID, string description)
    {
      this.DeviceID = deviceID;
      this.PnpDeviceID = pnpDeviceID;
      this.Description = description;
    }
    public string DeviceID { get; private set; }
    public string PnpDeviceID { get; private set; }
    public string Description { get; private set; }
  }
}

я знаю, что отвечаю на старый вопрос, но я просто прошел через это же упражнение и узнал немного больше информации, которая, я думаю, внесет большой вклад в Обсуждение и поможет всем, кто найдет этот вопрос и увидит, где существующие ответы не соответствуют.

The принято отвечать близко, и может быть исправлено с помощью Nedko комментарий к нему. Более детальное понимание задействованных классов WMI помогает завершить изображение.

Win32_USBHub возвращает только USB узлы. Это кажется очевидным в ретроспективе, но выше он не попадает. Он не включает в себя все возможные USB-устройства, только те, которые могут (по крайней мере, теоретически) выступать в качестве концентратора для дополнительных устройств. Он пропускает некоторые устройства, которые не являются концентраторами (особенно части составных устройств).

Win32_PnPEntity включает в себя все USB-устройства и сотни других устройств без USB. Рассела Гантмана советы чтобы использовать предложение WHERE search Win32_PnPEntity для DeviceID, начинающегося с " USB%", чтобы отфильтровать список, полезно, но немного неполно; он пропускает устройства bluetooth, некоторые принтеры/серверы печати и HID-совместимые мыши и клавиатуры. Я видел в "USB\%", "файлы usbstor\%", "восстановить\%", "ВТН\%", "ДСО\%", и "спрятался\%". Win32_PnPEntity является, однако, хорошей" главной " ссылкой для поиска информации, как только вы обладаете PNPDeviceID из других источников.

то, что я нашел, было лучшим способом перечисление USB-устройств было для запроса Win32_USBControllerDevice. Хотя он не дает подробной информации для устройств, он полностью перечисляет ваши USB-устройства и дает вам предшествующую / зависимую пару PNPDeviceIDs для каждого устройства USB (включая концентраторы, устройства без концентратора и устройства, совместимые с HID) в вашей системе. Каждый зависимый, возвращенный из запроса, будет USB-устройством. Антецедентом будет контроллер, которому он назначен, один из контроллеров USB, возвращенных запросом Win32_USBController.

в качестве бонуса, похоже, что под капотом, WMI ходит Дерево Устройства в ответ Win32_USBControllerDevice запрос, поэтому порядок, в котором эти результаты могут помочь определить отношения родитель/потомок. (Это не документировано и, таким образом, является только догадкой; используйте API SetupDi CM_Get_Parent (или ребенок + брат) для окончательных результатов.) В качестве опции для API SetupDi, похоже, что для всех устройств перечислены в разделе Win32_USBHub их можно посмотреть в реестре (на HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ + PNPDeviceID) и будет иметь параметр ParentIdPrefix который будет префиксом последнего поля в PNPDeviceID его дочерних элементов, так что это может также использоваться в подстановочном матче для фильтрации Win32_PnPEntity запрос.

в моем приложении, я сделал следующее:

  • (Опционально) Запрос Win32_PnPEntity и сохранил результаты в карте ключ-значение (с PNPDeviceID в качестве ключа) для последующего извлечения. Это необязательно, если вы хотите сделать отдельные запросы позже.
  • Queried Win32_USBControllerDevice для окончательного списка USB-устройств в моей системе (все иждивенцы) и извлекли PNPDeviceIDs из них. Я пошел дальше, основываясь на порядке следования за деревом устройств, чтобы назначить устройства корневому концентратору (первое возвращенное устройство, а не контроллер) и построил дерево на основе parentIdPrefix. Порядок, который возвращает запрос, который соответствует перечислению дерева устройств через SetupDi, является каждым корневым концентратором (для которого Антецедент идентифицирует контроллер), за которым следует итерация устройств под ним, например, в моей системе:
    • корневой концентратор первого контроллера
    • корневой концентратор второго контроллера
      • первый концентратор под корневым концентратором второго контроллера (имеет parentIdPrefix)
        • первое составное устройство под первым концентратором под корневым концентратором второго контроллера (PNPDeviceID соответствует выше ParentIdPrefix концентратора; имеет свой собственный ParentIdPrefix)
          • спрятанная часть прибора составного устройства (PNPDeviceID соответствует выше parentidprefix составного устройства)
        • второе устройство под первым концентратором под корневым концентратором второго контроллера
          • спрятанная часть прибора составного прибора
      • второй концентратор под корневым концентратором второго контроллера
        • первое устройство под вторым концентратором под корневым концентратором второго контроллера
      • третий хаб под корневой концентратор второго контроллера
      • etc.
  • Queried Win32_USBController. Это дало мне подробную информацию о PNPDeviceIDs моих контроллеров, которые находятся в верхней части дерева устройств (которые были предшественниками предыдущего запроса). Используя дерево, полученное на предыдущем шаге, рекурсивно перебирали его дочерние элементы (корневые концентраторы) и их дочерние элементы (другие концентраторы) и их дочерние элементы (устройства без концентраторов и составные устройства) и их дети и т. д.
    • полученные сведения для каждого устройства в моем дереве, ссылаясь на карту, сохраненную на первом шаге. (Необязательно, можно пропустить первый шаг и запросить Win32_PnPEntity индивидуально используя PNPDeviceId, чтобы получить информацию на этом шаге; вероятно, компромисс между процессором и памятью определяет, какой порядок лучше.)

в целом, Win32USBControllerDevice иждивенцы-это полный список USB-устройств в системе (кроме контроллеров сами, которые являются Антецедентами в том же запросе), и путем перекрестной ссылки на них PNPDeviceId пары с информацией из реестра и из других упомянутых запросов, детальная картина может быть построена.

чтобы увидеть устройства, которые меня интересовали, я должен был заменить Win32_USBHub by Win32_PnPEntity в коде Адель Хазза, на основе этот пост. Это работает для меня:

namespace ConsoleApplication1
{
  using System;
  using System.Collections.Generic;
  using System.Management; // need to add System.Management to your project references.

  class Program
  {
    static void Main(string[] args)
    {
      var usbDevices = GetUSBDevices();

      foreach (var usbDevice in usbDevices)
      {
        Console.WriteLine("Device ID: {0}, PNP Device ID: {1}, Description: {2}",
            usbDevice.DeviceID, usbDevice.PnpDeviceID, usbDevice.Description);
      }

      Console.Read();
    }

    static List<USBDeviceInfo> GetUSBDevices()
    {
      List<USBDeviceInfo> devices = new List<USBDeviceInfo>();

      ManagementObjectCollection collection;
      using (var searcher = new ManagementObjectSearcher(@"Select * From Win32_PnPEntity"))
        collection = searcher.Get();      

      foreach (var device in collection)
      {
        devices.Add(new USBDeviceInfo(
        (string)device.GetPropertyValue("DeviceID"),
        (string)device.GetPropertyValue("PNPDeviceID"),
        (string)device.GetPropertyValue("Description")
        ));
      }

      collection.Dispose();
      return devices;
    }
  }

  class USBDeviceInfo
  {
    public USBDeviceInfo(string deviceID, string pnpDeviceID, string description)
    {
      this.DeviceID = deviceID;
      this.PnpDeviceID = pnpDeviceID;
      this.Description = description;
    }
    public string DeviceID { get; private set; }
    public string PnpDeviceID { get; private set; }
    public string Description { get; private set; }
  }
}

Если вы измените ManagementObjectSearcher на следующее:

ManagementObjectSearcher searcher = 
       new ManagementObjectSearcher("root\CIMV2", 
       @"SELECT * FROM Win32_PnPEntity where DeviceID Like ""USB%"""); 

Так что "GetUSBDevices () выглядит так"

static List<USBDeviceInfo> GetUSBDevices()
{
  List<USBDeviceInfo> devices = new List<USBDeviceInfo>();

  ManagementObjectCollection collection;
  using (var searcher = new ManagementObjectSearcher(@"SELECT * FROM Win32_PnPEntity where DeviceID Like ""USB%"""))
    collection = searcher.Get();      

  foreach (var device in collection)
  {
    devices.Add(new USBDeviceInfo(
    (string)device.GetPropertyValue("DeviceID"),
    (string)device.GetPropertyValue("PNPDeviceID"),
    (string)device.GetPropertyValue("Description")
    ));
  }

  collection.Dispose();
  return devices;
}

}

ваши результаты будут ограничены USB-устройствами (в отличие от всех типов в вашей системе)

это гораздо более простой пример для людей, которые ищут только съемные USB-накопители.

using System.IO;

foreach (DriveInfo drive in DriveInfo.GetDrives())
{
    if (drive.DriveType == DriveType.Removable)
    {
        Console.WriteLine(string.Format("({0}) {1}", drive.Name.Replace("\",""), drive.VolumeLabel));
    }
}

вы можете найти этой теме полезное. А вот и google code project иллюстрируя это (он P / вызывает в setupapi.dll).

Адель Hazzah это ответ дает рабочий код, Дэниел Уиддис и Nedko это в комментариях упоминается, что вам нужно запросить Win32_USBControllerDevice и использовать его зависимое свойство, а Daniel's ответ дает много деталей без кода.

вот синтез приведенного выше обсуждения, чтобы обеспечить рабочий код, который перечисляет непосредственно доступные свойства устройства PNP всех подключенных USB устройства:

using System;
using System.Collections.Generic;
using System.Management; // reference required

namespace cSharpUtilities
{
    class UsbBrowser
    {

        public static void PrintUsbDevices()
        {
            IList<ManagementBaseObject> usbDevices = GetUsbDevices();

            foreach (ManagementBaseObject usbDevice in usbDevices)
            {
                Console.WriteLine("----- DEVICE -----");
                foreach (var property in usbDevice.Properties)
                {
                    Console.WriteLine(string.Format("{0}: {1}", property.Name, property.Value));
                }
                Console.WriteLine("------------------");
            }
        }

        public static IList<ManagementBaseObject> GetUsbDevices()
        {
            IList<string> usbDeviceAddresses = LookUpUsbDeviceAddresses();

            List<ManagementBaseObject> usbDevices = new List<ManagementBaseObject>();

            foreach (string usbDeviceAddress in usbDeviceAddresses)
            {
                // query MI for the PNP device info
                // address must be escaped to be used in the query; luckily, the form we extracted previously is already escaped
                ManagementObjectCollection curMoc = QueryMi("Select * from Win32_PnPEntity where PNPDeviceID = " + usbDeviceAddress);
                foreach (ManagementBaseObject device in curMoc)
                {
                    usbDevices.Add(device);
                }
            }

            return usbDevices;
        }

        public static IList<string> LookUpUsbDeviceAddresses()
        {
            // this query gets the addressing information for connected USB devices
            ManagementObjectCollection usbDeviceAddressInfo = QueryMi(@"Select * from Win32_USBControllerDevice");

            List<string> usbDeviceAddresses = new List<string>();

            foreach(var device in usbDeviceAddressInfo)
            {
                string curPnpAddress = (string)device.GetPropertyValue("Dependent");
                // split out the address portion of the data; note that this includes escaped backslashes and quotes
                curPnpAddress = curPnpAddress.Split(new String[] { "DeviceID=" }, 2, StringSplitOptions.None)[1];

                usbDeviceAddresses.Add(curPnpAddress);
            }

            return usbDeviceAddresses;
        }

        // run a query against Windows Management Infrastructure (MI) and return the resulting collection
        public static ManagementObjectCollection QueryMi(string query)
        {
            ManagementObjectSearcher managementObjectSearcher = new ManagementObjectSearcher(query);
            ManagementObjectCollection result = managementObjectSearcher.Get();

            managementObjectSearcher.Dispose();
            return result;
        }

    }

}

вам необходимо добавить обработку исключений, если вы этого хотите. Обратитесь к ответу Даниэля, если вы хотите выяснить дерево устройств и тому подобное.

Comments

    Ничего не найдено.