Як отримати список усіх підключених 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. Порада Рассела Гантмана використовувати Win32_PnPEntity
фільтр WHERE для пошуку DeviceID, що починається з "USB%", для фільтрування списку корисна, але дещо неповна; йому не вистачає пристроїв Bluetooth, деяких принтерів / серверів друку та HID-сумісних мишей та клавіатур. Я бачив "USB \%", "USBSTOR \%", "USBPRINT \%", "BTH \%", "SWD \%" та "HID \%". Win32_PnPEntity
однак є хорошим "головним" посиланням для пошуку інформації, як тільки у вас є PNPDeviceID з інших джерел.
Я знайшов найкращий спосіб перерахувати USB-пристрої - це запит Win32_USBControllerDevice
. Хоча він не надає детальної інформації про пристрої, він повністю перераховує ваші USB-пристрої та надає вам пару PNPDeviceID
s антецедентів / залежностей для кожного 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
. Це дало мені детальну інформацію про 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; }
}
}
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
робить?