Как я могу получить список всех подключенных USB-устройств на компьютере Windows?
Получить список подключенных USB-устройств
Ответ 1
Добавьте ссылку на 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; }
}
}
Ответ 2
Я знаю, что я отвечаю на старый вопрос, но я просто прошел через это же упражнение и узнал немного больше информации, что, я думаю, внесет большой вклад в обсуждение и поможет кому угодно, кто найдет этот вопрос и видит, где существующие ответы не совпадают.
принятый ответ близок и может быть исправлен с помощью комментария Nedko. Более подробное понимание вовлеченных классов WMI помогает завершить картину.
Win32_USBHub
возвращает только USB-концентраторы. Это кажется очевидным в ретроспективе, но обсуждение выше промахивается. Он не включает в себя все возможные USB-устройства, только те, которые могут (теоретически, по крайней мере) выступать в качестве концентратора для дополнительных устройств. Он пропускает некоторые устройства, которые не являются концентраторами (особенно части составных устройств).
Win32_PnPEntity
включает все USB-устройства и сотни других устройств, отличных от USB. Рекомендация Russel Gantman использовать поиск WHERE Win32_PnPEntity
для идентификатора устройства, начинающегося с "USB%" для фильтрации списка, полезно, но немного неполно; он пропускает HID-совместимые мыши и клавиатуры. Я считаю, что "USB \%", "USBSTOR \%", "USBPRINT \%" и "HID \%" будут полностью перечислять все возможности, но, поскольку есть лучшие варианты, это, вероятно, не нужно преследовать. Win32_PnPEntity
, однако, является хорошей "основной" ссылкой для поиска информации, когда вы владеете PNPDeviceID из других источников.
То, что я нашел, было лучшим способом перечислить USB-устройства, было запросить Win32_USBControllerDevice
. Хотя он не дает подробной информации для устройств, он полностью перечислил ваши USB-устройства и предоставил вам пару Antecedent/Dependent PNPDeviceID
для каждого устройства USB (включая концентраторы, устройства без хаба и устройства, совместимые с HID) в вашей системе. Каждый Зависимый, возвращенный из запроса, будет USB-устройством. Antecedent будет контроллером, которому он назначен, один из USB-контроллеров, возвращаемый запросом Win32_USBController
.
В качестве бонуса, похоже, что под капотом WMI проводит Дерево устройств при ответе на запрос Win32_USBControllerDevice
, поэтому порядок в котором эти результаты возвращаются, может помочь определить отношения родителя/ребенка. (Это не документировано и, следовательно, является лишь предположением, используйте API SetupDi CM_Get_Parent (или Ребенок + 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-устройства составного устройства
- Первое составное устройство под первым концентратором под корневым центром второго контроллера (PNPDeviceID совпадает с концентратором ParentIdPrefix; имеет свой собственный ParentIdPrefix)
- Второй концентратор под корневым центром второго контроллера
- Первое устройство под вторым концентратором под корневым центром второго контроллера.
- Третий концентратор под корневым центром второго контроллера
- и др.
- Первый концентратор под корневым центром второго контроллера (имеет parentIdPrefix)
- Запрос
Win32_USBController
. Это дало мне подробную информацию о параметрах PNPDeviceID моих контроллеров, которые находятся в верхней части дерева устройств (это были антецеденты предыдущего запроса). Используя дерево, полученное на предыдущем шаге, рекурсивно повторяем его дочерние элементы (корневые хабы) и их дочерние элементы (другие хабы) и их дочерние элементы (не-хаб-устройства и составные устройства) и их дочерние элементы и т.д.- Полученные данные для каждого устройства в моем дереве путем ссылки на карту, сохраненную на первом шаге. (Необязательно, можно пропустить первый шаг и запросить
Win32_PnPEntity
индивидуально, используя PNPDeviceId, чтобы получить информацию на этом шаге, вероятно, компиляция процессора и памяти, определяющая, какой порядок лучше.)
- Полученные данные для каждого устройства в моем дереве путем ссылки на карту, сохраненную на первом шаге. (Необязательно, можно пропустить первый шаг и запросить
Таким образом, Win32USBControllerDevice
Зависимые - это полный список USB-устройств в системе (кроме самих контроллеров, которые являются Антецедентами в этом же запросе) и путем перекрестной ссылки на эти пары PNPDeviceID
с информацией из в реестре и из других упомянутых запросов может быть построена подробная картина.
Ответ 3
Чтобы увидеть интересующие меня устройства, я заменил Win32_USBHub
на Win32_PnPEntity
в коде Adel Hazzah на основе этого сообщения. Это работает для меня:
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; }
}
}
Ответ 4
Если вы измените 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 (в отличие от всех типов в вашей системе)
Ответ 5
Вы можете найти этот поток полезный. И здесь проект кода google, иллюстрирующий это (он P/вызывает в setupapi.dll
).
Ответ 6
Это гораздо более простой пример для людей, которые ищут только съемные 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));
}
}
Ответ 7
Adel Hazzah answer дает рабочий код Daniel Widdis и В комментариях Nedko упоминается, что вам нужно запросить Win32_USBControllerDevice и использовать его свойство Dependent, а Daniel answer дает много деталей без кода.
Здесь приведено обобщение вышеприведенного обсуждения, чтобы предоставить рабочий код, в котором перечислены свойства доступного 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;
}
}
}
Вам нужно будет добавить обработку исключений, если хотите. Проконсультируйтесь с Дэниэлом, если вы хотите выяснить дерево устройства и т.д.