Comment puis-je obtenir une liste de tous les périphériques USB connectés sur un ordinateur Windows?
Réponses:
Ajoutez une référence à System.Management pour votre projet, puis essayez quelque chose comme ceci:
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; }
}
}
Je sais que je réponds à une vieille question, mais je viens de faire le même exercice et j'ai trouvé un peu plus d'informations, qui, je pense, contribueront beaucoup à la discussion et aideront toute autre personne qui trouve cette question et voit où le les réponses existantes sont insuffisantes.
La réponse acceptée est proche et peut être corrigée en utilisant le commentaire de Nedko . Une compréhension plus détaillée des classes WMI impliquées permet de compléter le tableau.
Win32_USBHub
renvoie uniquement les concentrateurs USB . Cela semble évident avec le recul, mais la discussion ci-dessus manque. Il n'inclut pas tous les périphériques USB possibles, seulement ceux qui peuvent (au moins en théorie) servir de hub pour des périphériques supplémentaires. Il manque certains appareils qui ne sont pas des concentrateurs (en particulier des parties d'appareils composites).
Win32_PnPEntity
inclut tous les périphériques USB et des centaines d'autres périphériques non USB. Le conseil de Russel Gantman d'utiliser une clause WHERE recherche Win32_PnPEntity
un DeviceID commençant par "USB%" pour filtrer la liste est utile mais légèrement incomplet; il manque des périphériques Bluetooth, certaines imprimantes / serveurs d'impression et des souris et claviers compatibles HID. J'ai vu "USB \%", "USBSTOR \%", "USBPRINT \%", "BTH \%", "SWD \%" et "HID \%". Win32_PnPEntity
est, cependant, une bonne référence "principale" pour rechercher des informations une fois que vous êtes en possession du PNPDeviceID provenant d'autres sources.
Ce que j'ai trouvé, c'est que le meilleur moyen d'énumérer les périphériques USB était d'interroger Win32_USBControllerDevice
. Bien qu'il ne donne pas d'informations détaillées sur les périphériques, il énumère complètement vos périphériques USB et vous donne une paire de PNPDeviceID
s Antécédent / Dépendant pour chaque périphérique USB (y compris les concentrateurs, les périphériques non-Hub et les périphériques compatibles HID) sur votre système. Chaque Dépendant renvoyé par la requête sera un périphérique USB. L'antécédent sera le contrôleur auquel il est assigné, l'un des contrôleurs USB renvoyé par l'interrogation Win32_USBController
.
En prime, il semble que sous le capot, WMI parcourt l' arborescence des périphériques en répondant à la Win32_USBControllerDevice
requête, de sorte que l'ordre dans lequel ces résultats sont renvoyés peut aider à identifier les relations parent / enfant. (Ceci n'est pas documenté et n'est donc qu'une supposition; utilisez CM_Get_Parent (ou Child + Sibling ) de l'API SetupDi pour des résultats définitifs.) En tant qu'option de l'API SetupDi, il semble que pour tous les périphériques répertoriés sous Win32_USBHub
ils peuvent être recherchés dans le registre (at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ + PNPDeviceID
) et aura un paramètre ParentIdPrefix
qui sera le préfixe du dernier champ dans le PNPDeviceID de ses enfants, donc cela pourrait également être utilisé dans une correspondance générique pour filtrer la Win32_PnPEntity
requête.
Dans ma candidature, j'ai fait ce qui suit:
Win32_PnPEntity
et stocké les résultats dans une mappe clé-valeur (avec PNPDeviceID comme clé) pour une récupération ultérieure. Ceci est facultatif si vous souhaitez effectuer des requêtes individuelles ultérieurement.Win32_USBControllerDevice
pour une liste définitive des périphériques USB sur mon système (toutes les personnes à charge) et extrait les PNPDeviceID de ceux-ci. Je suis allé plus loin, en fonction de l'ordre suivant l'arborescence des périphériques, pour attribuer des périphériques au hub racine (le premier périphérique est retourné, plutôt que le contrôleur) et j'ai construit une arborescence basée sur le parentIdPrefix. L'ordre renvoyé par la requête, qui correspond à l'énumération de l'arborescence des périphériques via SetupDi, correspond à chaque hub racine (pour lequel l'Antecedent identifie le contrôleur), suivi d'une itération des périphériques sous celui-ci, par exemple sur mon système:
Win32_USBController
. Cela m'a donné les informations détaillées des PNPDeviceID de mes contrôleurs qui se trouvent en haut de l'arborescence des périphériques (qui étaient les antécédents de la requête précédente). Utilisation de l'arborescence dérivée à l'étape précédente, itérée de manière récursive sur ses enfants (les hubs racine) et leurs enfants (les autres hubs) et leurs enfants (appareils non hubs et appareils composites) et leurs enfants, etc.
Win32_PnPEntity
individuellement en utilisant le PNPDeviceId pour obtenir les informations à cette étape; probablement un compromis CPU / mémoire déterminant quel ordre est le meilleur.)En résumé, les personnes à Win32USBControllerDevice
charge sont une liste complète des périphériques USB sur un système (autres que les contrôleurs eux-mêmes, qui sont les antécédents dans cette même requête), et en croisant ces PNPDeviceId
paires avec des informations du registre et des autres requêtes mentionnées, une image détaillée peut être construite.
Pour voir les appareils qui m'intéressaient, j'avais remplacé Win32_USBHub
par Win32_PnPEntity
dans le code d'Adel Hazzah, basé sur ce post . Cela fonctionne pour moi:
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 réponse d' Adel Hazzah donne un code de travail, les commentaires de Daniel Widdis et Nedko mentionnent que vous devez interroger Win32_USBControllerDevice et utiliser sa propriété Dependent, et la réponse de Daniel donne beaucoup de détails sans code.
Voici une synthèse de la discussion ci-dessus pour fournir un code de travail qui répertorie les propriétés de périphérique PNP directement accessibles de tous les périphériques USB connectés:
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;
}
}
}
Vous devrez ajouter la gestion des exceptions si vous le souhaitez. Consultez la réponse de Daniel si vous voulez comprendre l'arborescence des appareils et autres.
Il s'agit d'un exemple beaucoup plus simple pour les personnes qui recherchent uniquement des lecteurs USB amovibles.
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));
}
}
Si vous modifiez ManagementObjectSearcher comme suit:
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
@"SELECT * FROM Win32_PnPEntity where DeviceID Like ""USB%""");
Donc, le "GetUSBDevices () ressemble à ceci"
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;
}
}
Vos résultats seront limités aux périphériques USB (par opposition à tous les types sur votre système)
Vous pouvez trouver ce fil utile. Et voici un projet de code google illustrant cela (il P / Invokes 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
ça fait?