Come posso ottenere un elenco di tutti i dispositivi USB collegati su un computer Windows?
Risposte:
Aggiungi un riferimento a System.Management per il tuo progetto, quindi prova qualcosa di simile:
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; }
}
}
So di rispondere a una vecchia domanda, ma ho appena svolto lo stesso esercizio e ho scoperto un po 'più di informazioni, che penso contribuiranno molto alla discussione e aiuteranno chiunque trovi questa domanda e vedrà dove le risposte esistenti sono insufficienti.
La risposta accettata è vicina e può essere corretta utilizzando il commento di Nedko . Una comprensione più dettagliata delle classi WMI coinvolte aiuta a completare il quadro.
Win32_USBHub
restituisce solo hub USB . Ciò sembra ovvio con il senno di poi, ma la discussione di cui sopra manca. Non include tutti i possibili dispositivi USB, solo quelli che possono (in teoria, almeno) fungere da hub per dispositivi aggiuntivi. Mancano alcuni dispositivi che non sono hub (in particolare parti di dispositivi compositi).
Win32_PnPEntity
include tutti i dispositivi USB e centinaia di altri dispositivi non USB. Il consiglio di Russel Gantman di utilizzare una clausola WHERE Win32_PnPEntity
per cercare un DeviceID che inizia con "USB%" per filtrare l'elenco è utile ma leggermente incompleto; manca i dispositivi Bluetooth, alcune stampanti / server di stampa e mouse e tastiere compatibili con HID. Ho visto "USB \%", "USBSTOR \%", "USBPRINT \%", "BTH \%", "SWD \%" e "HID \%". Win32_PnPEntity
è, tuttavia, un buon riferimento "master" per cercare informazioni una volta che si è in possesso del PNPDeviceID da altre fonti.
Quello che ho trovato è che il modo migliore per enumerare i dispositivi USB era interrogare Win32_USBControllerDevice
. Sebbene non fornisca informazioni dettagliate per i dispositivi, enumera completamente i tuoi dispositivi USB e ti fornisce una coppia di antecedenti / dipendenti PNPDeviceID
per ogni dispositivo USB (inclusi Hub, dispositivi non Hub e dispositivi compatibili HID) sul tuo sistema. Ogni dipendente restituito dalla query sarà un dispositivo USB. L'antecedente sarà il controller a cui è assegnato, uno dei controller USB restituiti dalla query Win32_USBController
.
Come bonus, sembra che sotto il cofano, WMI percorra la struttura dei dispositivi quando risponde alla Win32_USBControllerDevice
query, quindi l'ordine in cui vengono restituiti questi risultati può aiutare a identificare le relazioni padre / figlio. (Questo non è documentato ed è quindi solo una supposizione; usa CM_Get_Parent (o Child + Sibling ) dell'API SetupDi per risultati definitivi.) Come opzione per l'API SetupDi, sembra che per tutti i dispositivi elencati sotto Win32_USBHub
possano essere cercati nel registro (at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ + PNPDeviceID
) e avrà un parametro ParentIdPrefix
che sarà il prefisso dell'ultimo campo nel PNPDeviceID dei suoi figli, quindi questo potrebbe essere utilizzato anche in una corrispondenza con caratteri jolly per filtrare la Win32_PnPEntity
query.
Nella mia domanda, ho fatto quanto segue:
Win32_PnPEntity
e memorizzazione dei risultati in una mappa valore-chiave (con PNPDeviceID come chiave) per il successivo recupero. Questo è facoltativo se desideri eseguire singole query in un secondo momento.Win32_USBControllerDevice
un elenco definitivo dei dispositivi USB sul mio sistema (tutti i dipendenti) ed ho estratto i PNPDeviceID di questi. Sono andato oltre, in base all'ordine che segue l'albero dei dispositivi, per assegnare i dispositivi all'hub principale (il primo dispositivo restituito, piuttosto che al controller) e ho costruito un albero basato su parentIdPrefix. L'ordine restituito dalla query, che corrisponde all'enumerazione dell'albero dei dispositivi tramite SetupDi, è ciascun hub principale (per il quale l'Antecedente identifica il controller), seguito da un'iterazione dei dispositivi sotto di esso, ad esempio, sul mio sistema:
Win32_USBController
. Questo mi ha fornito le informazioni dettagliate dei PNPDeviceID dei miei controller che si trovano nella parte superiore dell'albero dei dispositivi (che erano gli antecedenti della query precedente). Utilizzando l'albero derivato nel passaggio precedente, iterato ricorsivamente sui suoi figli (gli hub radice) e sui loro figli (gli altri hub) e sui loro figli (dispositivi non hub e dispositivi compositi) e sui loro figli, ecc.
Win32_PnPEntity
individualmente utilizzando PNPDeviceId per ottenere le informazioni in questo passaggio; probabilmente un compromesso tra CPU e memoria che determina quale ordine è migliore.)In sintesi, i Win32USBControllerDevice
dipendenti sono un elenco completo di dispositivi USB su un sistema (diversi dai controller stessi, che sono gli antecedenti nella stessa query) e facendo un riferimento incrociato a queste PNPDeviceId
coppie con le informazioni del registro e delle altre query menzionate, si può costruire un'immagine dettagliata.
Per vedere i dispositivi che mi interessavano, ho dovuto sostituirli Win32_USBHub
con Win32_PnPEntity
nel codice di Adel Hazzah, basato su questo post . Questo funziona per me:
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; }
}
}
La risposta di Adel Hazzah fornisce un codice funzionante, i commenti di Daniel Widdis e Nedko menzionano che è necessario interrogare Win32_USBControllerDevice e utilizzare la sua proprietà Dependent, e la risposta di Daniel fornisce molti dettagli senza codice.
Ecco una sintesi della discussione sopra per fornire un codice funzionante che elenca le proprietà del dispositivo PNP direttamente accessibili di tutti i dispositivi USB collegati:
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;
}
}
}
Dovrai aggiungere la gestione delle eccezioni se lo desideri. Consulta la risposta di Daniel se vuoi capire l'albero dei dispositivi e simili.
Questo è un esempio molto più semplice per le persone che cercano solo unità USB rimovibili.
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));
}
}
Se si modifica ManagementObjectSearcher nel seguente:
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
@"SELECT * FROM Win32_PnPEntity where DeviceID Like ""USB%""");
Quindi "GetUSBDevices () ha questo aspetto"
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;
}
}
I risultati saranno limitati ai dispositivi USB (al contrario di tutti i tipi sul tuo sistema)
Potresti trovare utile questo thread . Ed ecco un progetto di codice Google che esemplifica questo (P / Invoca in 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
?