100 votes

Obtenir la liste des périphériques USB connectés

Comment puis-je obtenir une liste de tous les périphériques USB connectés sur un ordinateur Windows ?

130voto

Adel Hazzah Points 2860

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; }
  }
}

14 votes

Existe-t-il un moyen de récupérer le nom convivial du périphérique ? Par exemple, lorsque j'entre dans les propriétés de ma clé USB, je vois "Kingston DataTraveler 2.0 USB Device".

2 votes

Quelle est la différence entre DeviceID et PNPDeviceID ?

1 votes

Lorsque j'exécute le programme ci-dessus, j'obtiens mes disques durs USB, mon clavier et ma souris, mais je n'obtiens pas ma caméra USB, mon A/D USB. Pourquoi tous mes périphériques USB n'apparaissent-ils pas ?

50voto

Daniel Widdis Points 1516

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ù les réponses existantes sont insuffisantes.

El réponse acceptée est proche, et peut être corrigée en utilisant Commentaire de Nedko à celui-ci. Une compréhension plus détaillée des classes WMI concernées permet de compléter le tableau.

Win32_USBHub ne renvoie que l'USB Moyeux . Cela semble évident avec le recul, mais la discussion ci-dessus passe à côté. Elle n'inclut pas tous les dispositifs USB possibles, mais seulement ceux qui peuvent (en théorie, du moins) servir de hub pour des dispositifs supplémentaires. Il manque certains dispositifs qui ne sont pas des concentrateurs (en particulier des parties de dispositifs composites).

Win32_PnPEntity comprend tous les périphériques USB, et des centaines d'autres périphériques non-USB. Russel Gantman conseils pour utiliser une recherche par clause WHERE Win32_PnPEntity La recherche d'un DeviceID commençant par " USB% " pour filtrer la liste est utile mais légèrement incomplète ; elle ne prend pas en compte les périphériques Bluetooth, certaines imprimantes/serveurs d'impression, ainsi que les 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 la meilleure façon 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 Antécédent/Dépendant de PNPDeviceID pour chaque dispositif USB (y compris les concentrateurs, les dispositifs sans concentrateur et les dispositifs conformes à la norme HID) sur votre système. Chaque dépendant renvoyé par la requête sera un dispositif USB. L'antécédent sera le contrôleur auquel il est affecté, l'un des contrôleurs USB renvoyés par la requête Win32_USBController .

En prime, il semblerait que sous le capot, WMI promène les Arbre des dispositifs en répondant à la Win32_USBControllerDevice 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 l'API de SetupDi CM_Get_Parent (ou Enfant + Frères et sœurs ) pour des résultats définitifs). En tant qu'option de l'API SetupDi, il semble que pour tous les appareils répertoriés dans la rubrique Win32_USBHub ils peuvent être recherchés dans le registre (à l'adresse 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, de sorte qu'il pourrait également être utilisé dans une correspondance joker pour filtrer le fichier Win32_PnPEntity requête.

Dans ma demande, j'ai fait ce qui suit :

  • (Facultatif) Interrogé Win32_PnPEntity et stocke les résultats dans une carte clé-valeur (avec PNPDeviceID comme clé) pour une récupération ultérieure. Cette opération est facultative si vous souhaitez effectuer des requêtes individuelles ultérieurement.
  • Demande de renseignements Win32_USBControllerDevice pour une liste définitive des périphériques USB sur mon système (tous les Dependents) et extrait les PNPDeviceIDs de ceux-ci. Je suis allé plus loin, en me basant sur l'ordre suivant l'arbre des périphériques, pour affecter les périphériques au hub racine (le premier périphérique renvoyé, plutôt que le contrôleur) et j'ai construit un arbre basé sur le parentIdPrefix. L'ordre que la requête renvoie, qui correspond à l'énumération de l'arbre des périphériques via SetupDi, est chaque hub racine (pour lequel l'antécédent identifie le contrôleur), suivi d'une itération de périphériques sous celui-ci, par exemple, sur mon système :
    • Moyeu racine du premier contrôleur
    • Moyeu racine du deuxième contrôleur
      • Premier concentrateur sous le concentrateur racine du deuxième contrôleur (a parentIdPrefix)
        • Premier dispositif composite sous le premier concentrateur sous le concentrateur racine du deuxième contrôleur (PNPDeviceID correspond au ParentIdPrefix du concentrateur ci-dessus ; a son propre ParentIdPrefix)
          • HID Dispositif faisant partie du dispositif composite (PNPDeviceID correspond au ParentIDPrefix du dispositif composite ci-dessus)
        • Deuxième dispositif sous le premier hub sous le hub Root du deuxième contrôleur
          • Dispositif HID faisant partie du dispositif composite
      • Second hub sous Root hub du second contrôleur
        • Premier dispositif sous le second hub sous le hub Root du second contrôleur
      • Troisième hub sous le hub racine du deuxième contrôleur
      • etc.
  • Demande de renseignements Win32_USBController . J'ai ainsi obtenu les informations détaillées sur les PNPDeviceID de mes contrôleurs qui se trouvent au sommet de l'arbre des périphériques (qui étaient les antécédents de la requête précédente). En utilisant l'arbre dérivé à l'étape précédente, j'ai itéré de façon récursive sur ses enfants (les hubs racine) et leurs enfants (les autres hubs) et leurs enfants (les périphériques non hubs et les périphériques composites) et leurs enfants, etc.
    • J'ai récupéré les détails de chaque appareil dans mon arbre en faisant référence à la carte stockée dans la première étape. (En option, on peut sauter la première étape, et demander à Win32_PnPEntity en utilisant individuellement le PNPDeviceId pour obtenir l'information à cette étape ; probablement un compromis cpu vs. mémoire pour déterminer quel ordre est le meilleur).

En résumé, Win32USBControllerDevice Les dépendants 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 derniers PNPDeviceId couplées aux informations du registre et des autres requêtes mentionnées, une image détaillée peut être construite.

16voto

ocroquette Points 126

Pour voir les appareils qui m'intéressaient, je devais remplacer Win32_USBHub par Win32_PnPEntity dans le code d'Adel Hazzah, basé sur ce poste . 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; }
  }
}

0 votes

Cela a bien fonctionné. Pour faciliter la détermination de l'appareil que vous venez de brancher, écrivez-le pour qu'il s'exécute à un intervalle, écrivez les entrées dans un dictionnaire et signalez tout ajout depuis la dernière fois que vous l'avez exécuté.

8voto

Tydaeus Points 1173

Adel Hazzah réponse donne un code fonctionnel, Daniel Widdis y Nedko's mentionnent qu'il faut interroger Win32_USBControllerDevice et utiliser sa propriété Dependent, et les commentaires de Daniel réponse donne beaucoup de détails sans code.

Voici une synthèse de la discussion ci-dessus pour fournir un code fonctionnel qui liste les propriétés des périphériques 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'arbre des périphériques et autres.

6voto

Russell Gantman Points 211

Si vous modifiez le ManagementObjectSearcher comme suit :

ManagementObjectSearcher searcher = 
       new ManagementObjectSearcher("root\\CIMV2", 
       @"SELECT * FROM Win32_PnPEntity where DeviceID Like ""USB%"""); 

Donc le "GetUSBDevices() ressemble à ça".

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 de périphériques présents sur votre système).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X