Как я могу получить список всех подключенных USB-устройств на компьютере с Windows?
Ответы:
Добавьте ссылку на 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 PNPDeviceID
для каждого USB-устройства (включая концентраторы, устройства, не являющиеся концентраторами, и устройства, совместимые с HID) на вашем система. Каждый зависимый, возвращенный из запроса, будет USB-устройством. Антецедентом будет контроллер, которому он назначен, один из контроллеров USB, возвращенный запросом Win32_USBController
.
В качестве бонуса оказывается, что под капотом WMI просматривает дерево устройств при ответе на Win32_USBControllerDevice
запрос, поэтому порядок, в котором возвращаются эти результаты, может помочь определить отношения родитель / потомок. (Это не задокументировано и, таким образом, является лишь предположением; для окончательных результатов используйте CM_Get_Parent (или Child + Sibling ) API SetupDi .) Как вариант для API SetupDi, похоже, что для всех устройств, перечисленных в разделе, Win32_USBHub
они могут быть найдены в реестре (at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ + PNPDeviceID
) и будет иметь параметр, ParentIdPrefix
который будет префиксом последнего поля в PNPDeviceID его дочерних элементов, поэтому его также можно использовать в сопоставлении с подстановочными знаками для фильтрации Win32_PnPEntity
запроса.
В своем приложении я сделал следующее:
Win32_PnPEntity
и сохранены результаты в карте значения ключа (с PNPDeviceID в качестве ключа) для последующего извлечения. Это необязательно, если вы хотите выполнять отдельные запросы позже.Win32_USBControllerDevice
список USB-устройств в моей системе (все зависимые) и извлечены их PNPDeviceID. Я пошел дальше, основываясь на порядке следования дерева устройств, чтобы назначить устройства корневому концентратору (первое возвращенное устройство, а не контроллер) и построил дерево на основе parentIdPrefix. Порядок, возвращаемый запросом, который соответствует перечислению дерева устройств через SetupDi, представляет собой каждый корневой концентратор (для которого Antecedent идентифицирует контроллер), за которым следует итерация устройств под ним, например, в моей системе:
Win32_USBController
. Это дало мне подробную информацию о PNPDeviceID моих контроллеров, которые находятся наверху дерева устройств (которые были антецедентами предыдущего запроса). Используя дерево, полученное на предыдущем шаге, рекурсивно перебирает его дочерние элементы (корневые концентраторы) и их дочерние элементы (другие концентраторы) и их дочерние элементы (устройства, не являющиеся концентраторами и составные устройства) и их дочерние элементы и т. Д.
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; }
}
}
Adel Hazzah в ответ дает рабочий код, Daniel Widdis - х и Недко в комментарии упомянуть , что вам нужно запросить 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;
}
}
}
Вам нужно будет добавить обработку исключений, если вы этого хотите. Обратитесь к ответу Дэниела, если вы хотите выяснить дерево устройств и тому подобное.
Это гораздо более простой пример для людей, которые ищут только съемные 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));
}
}
Если вы измените 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-устройствами (в отличие от всех типов в вашей системе)
Вы можете найти эту ветку полезной. И вот проект кода Google, иллюстрирующий это (он P / вызывает setupapi.dll
).
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);
}
}
}
}
object value
делает?