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

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

9 ответов

Решение

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

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; }
  }
}

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

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

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

Win32_PnPEntity действительно включает в себя все USB-устройства и сотни других не-USB-устройств. Совет Рассела Гантмана использовать поиск предложения WHERE Win32_PnPEntity для DeviceID, начинающегося с "USB%", фильтрация списка полезна, но немного неполна; он пропускает устройства Bluetooth, некоторые принтеры / серверы печати, а также HID-совместимые мыши и клавиатуры. Я видел "USB\%", "USBSTOR\%", "USBPRINT\%", "BTH\%", "SWD\%" и "HID\%". Win32_PnPEntity однако, это хорошая "основная" ссылка для поиска информации, если у вас есть PNPDeviceID из других источников.

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

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

В своем заявлении я сделал следующее:

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

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

Чтобы увидеть интересующие меня устройства, мне пришлось заменить Win32_USBHub от 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; }
  }
}

Ответ Аделя Хаззы дает рабочий код, Nedko комментариях Дэниела Виддиса и Nedko упоминается, что вам нужно запросить Win32_USBControllerDevice и использовать его свойство Dependent, а в ответе Дэниела содержится много деталей без кода.

Вот обобщение вышеприведенного обсуждения, чтобы предоставить рабочий код, который перечисляет непосредственно доступные свойства устройства 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;
        }

    }

}

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

Если вы измените 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, иллюстрирующий это (это P/ Вызывает в setupapi.dll).

Это улучшает ответ, который написал Тидей: /questions/17626496/poluchit-spisok-podklyuchennyih-usb-ustrojstv/17626510#17626510

Вопрос звучит так: «Как я могу получить список всех подключенных USB-устройств на компьютере с Windows?» и USB-концентратор, например, — это не совсем то, что мне хотелось бы видеть в этом списке.

Поэтому я добавил пример, как исключить класс устройств, например USB-концентраторы.

Список классов, таких как

https://learn.microsoft.com/en-us/windows-hardware/drivers/install/guid-devinterface-mouse

https://learn.microsoft.com/en-us/windows-hardware/drivers/install/guid-devinterface-keyboard

находится здесь: https://learn.microsoft.com/en-us/windows-hardware/drivers/install/system-define-device-setup-classes-available-to-vendors

но есть и другие возможные классы, например USB-концентраторы:

https://learn.microsoft.com/en-us/windows-hardware/drivers/install/guid-devinterface-usb-hub

Он также отображает VID устройства (идентификатор поставщика), PID (идентификатор продукта) и серийный номер, если кому-то интересно.

      using System;
using System.Collections.Generic;
using System.Management;

/*
ClassGuid for USB hubs: {36fc9e60-c465-11cf-8056-444553540000} The identifier is GUID_DEVINTERFACE_USB_HUB
ClassGuid for network adapters: {4d36e972-e325-11ce-bfc1-08002be10318} The identifier is GUID_DEVINTERFACE_NET
ClassGuid for HID devices: {745a17a0-74d3-11d0-b6fe-00a0c90f57da} The identifier is GUID_DEVINTERFACE_HID
ClassGuid for mice: {4d36e96f-e325-11ce-bfc1-08002be10318} The identifier is GUID_DEVINTERFACE_MOUSE
ClassGuid for keyboards: {4d36e96b-e325-11ce-bfc1-08002be10318} The identifier is GUID_DEVINTERFACE_KEYBOARD

https://learn.microsoft.com/en-us/windows-hardware/drivers/install/system-defined-device-setup-classes-available-to-vendors
/**/

class Program
{
    static void Main(string[] args)
    {
        IList<ManagementBaseObject> usbDevices = GetUsbDevices();

        foreach (ManagementBaseObject usbDevice in usbDevices)
        {
            string classGuid = (string)usbDevice["ClassGuid"];

            // you can exclude a device class, for example USB hubs:
            if (classGuid == "{36fc9e60-c465-11cf-8056-444553540000}")
                continue;

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

            string deviceID = (string)usbDevice["DeviceID"];

            if (deviceID.Contains("VID_") && deviceID.Contains("PID_"))
            {
                string[] splitDeviceID = deviceID.Split('\\');
                string[] splitVidPid = splitDeviceID[splitDeviceID.Length - 2].Split('&');

                string vid = splitVidPid[0].Split('_')[1];
                string pid = splitVidPid[1].Split('_')[1];
                string serialNumber = splitDeviceID[splitDeviceID.Length - 1];

                Console.WriteLine("VID: {0}", vid);
                Console.WriteLine("PID: {0}", pid);
                Console.WriteLine("Serial Number: {0}", serialNumber);
            }

            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;
    }
}

  lstResult.Clear();
  foreach (ManagementObject drive in new ManagementObjectSearcher("select * from Win32_DiskDrive where InterfaceType='USB'").Get())
  {
       foreach (ManagementObject partition in new ManagementObjectSearcher("ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + drive["DeviceID"] + "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition").Get())
       {
            foreach (ManagementObject disk in new ManagementObjectSearcher("ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" + partition["DeviceID"] + "'} WHERE AssocClass = Win32_LogicalDiskToPartition").Get())
            {
                  foreach (var item in disk.Properties)
                  {
                       object value = disk.GetPropertyValue(item.Name);
                  }
                  string valor = disk["Name"].ToString();
                  lstResult.Add(valor);
                  }
             }
        }
   }
Другие вопросы по тегам