Bağlı USB Cihazlarının Listesini Alın


93

Windows bilgisayarına bağlı tüm USB cihazlarının listesini nasıl alabilirim?

Yanıtlar:


123

Projeniz için System.Management'a bir referans ekleyin, ardından şuna benzer bir şey deneyin:

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
Cihazın kolay adını almanın bir yolu var mı? Örneğin, usb belleğimin özelliklerine girdiğimde "Kingston DataTraveler 2.0 USB Aygıtı" görüyorum.
Robert

2
DeviceID ve PNPDeviceID arasındaki fark nedir?
Shimmy Weitzhandler

1
Yukarıdaki programı çalıştırdığımda, USB Sabit disklerimi, klavyemi ve faremi alıyorum, ancak USB kameramı, USB A / D'mi alamıyorum. Neden tüm USB cihazlarım görünmüyor?
Curt

8
tüm usb cihazların listesini almak için "Win32_USBHub" değil "Win32_USBControllerDevice" sorgulanmalıdır. Ardından, cihaz adres dizesini almak için "Bağımlı" özelliğini kullanın.
Nedko

1
@ppumkin Win32_USBHubyalnızca USB Hub'ları içerir, tüm cihazları değil, bu nedenle bazı cihazları kaçırıyorsunuz. @nedko, Win32_USBControllerDevicetüm cihazları almak için Bağımlı özelliğini almanız gerektiği konusunda doğru .
Daniel Widdis

45

Eski bir soruyu yanıtladığımı biliyorum, ancak aynı alıştırmadan geçtim ve biraz daha fazla bilgi edindim, tartışmaya çok katkıda bulunacağını ve bu soruyu bulan ve nerede olduğunu gören herkese yardımcı olacağını düşündüğüm mevcut cevaplar yetersiz kalır.

Kabul edilen cevap yakındır ve Nedko'nun yorumu kullanılarak düzeltilebilir . İlgili WMI Sınıflarının daha ayrıntılı bir şekilde anlaşılması, resmin tamamlanmasına yardımcı olur.

Win32_USBHubyalnızca USB Hub'larını döndürür . Geriye dönüp bakıldığında bu açık görünüyor ancak yukarıdaki tartışma bunu kaçırıyor. Olası tüm USB aygıtlarını içermez, yalnızca (en azından teorik olarak) ek aygıtlar için bir hub işlevi görebilenler. Hub olmayan bazı cihazları (özellikle bileşik cihazların parçaları) gözden kaçırır.

Win32_PnPEntitytüm USB aygıtlarını ve yüzlerce USB olmayan aygıtı içerir. Russel Gantman'ınWin32_PnPEntity , listeyi filtrelemek için "USB%" ile başlayan bir DeviceID için bir WHERE deyimi aramasını kullanma tavsiyesi yararlıdır, ancak biraz eksiktir; bluetooth aygıtlarını, bazı yazıcıları / yazıcı sunucularını ve HID uyumlu fareleri ve klavyeleri özlüyor. "USB \%", "USBSTOR \%", "USBPRINT \%", "BTH \%", "SWD \%" ve "HID \%" gördüm. Win32_PnPEntityancak, diğer kaynaklardan PNPDeviceID'ye sahip olduğunuzda bilgi aramak için iyi bir "ana" referanstır.

Bulduğum şey, USB cihazlarını numaralandırmanın en iyi yolu sorgulamaktı Win32_USBControllerDevice. Cihazlar için ayrıntılı bilgi vermezken, USB cihazlarınızı tam olarak numaralandırır ve cihazınızdaki PNPDeviceIDher USB Cihazı (Hub'lar, Hub olmayan cihazlar ve HID uyumlu cihazlar dahil) için size bir Antecedent / Dependent çifti verir . sistemi. Sorgudan döndürülen her Bağımlı, bir USB Aygıtı olacaktır. Öncü, sorgulama ile döndürülen USB Denetleyicilerinden biri olan atandığı Denetleyici olacaktır Win32_USBController.

Bir bonus olarak, WMI'nin sorguya yanıt verirken Aygıt Ağacını gezdiği ve Win32_USBControllerDevicebu sonuçların döndürülme sırasının üst / alt ilişkilerinin belirlenmesine yardımcı olabileceği görülüyor . (Bu belgelenmiş ve böylece sadece bir tahmin olduğunu değildir; SetupDi API kullanmak CM_Get_Parent (veya Çocuk + Kardeş . Kesin sonuç için)) SetupDi API için bir seçenek olarak, tüm cihazlar listelenmiş için altında görünür Win32_USBHubonlar aranabilir kayıt defterinde (at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ + PNPDeviceID) ve ParentIdPrefixalt öğelerinin PNPDeviceID'sindeki son alanın öneki olacak bir parametreye sahip olacaktır, bu nedenle bu, Win32_PnPEntitysorguyu filtrelemek için joker karakter eşleşmesinde de kullanılabilir .

Başvurumda şunları yaptım:

  • (İsteğe bağlı) Win32_PnPEntitySonuçları, daha sonra alınmak üzere bir anahtar-değer eşlemesinde (anahtar olarak PNPDeviceID ile) sorguladı ve depoladı. Daha sonra tek tek sorgular yapmak istiyorsanız bu isteğe bağlıdır.
  • Win32_USBControllerDeviceSistemimdeki (tüm Bağımlılar) USB cihazlarının kesin bir listesi için sorgulandım ve bunların PNPDeviceID'lerini çıkardım. Aygıt ağacını izleyen sıraya göre, aygıtları kök hub'a atamak için daha da ileri gittim (denetleyici yerine döndürülen ilk aygıt) ve parentIdPrefix'e dayalı bir ağaç oluşturdum. SetupDi aracılığıyla cihaz ağacı numaralandırmasıyla eşleşen sorgunun döndürdüğü sıra, her bir kök merkezdir (bunun için Öncü, denetleyiciyi tanımlar), ardından bunun altındaki aygıtların bir yinelemesi, örneğin sistemimde:
    • İlk denetleyicinin kök merkezi
    • İkinci denetleyicinin kök merkezi
      • İkinci denetleyicinin kök hub'ı altındaki ilk hub (parentIdPrefix'e sahiptir)
        • İkinci denetleyicinin kök hub'ı altındaki birinci hub altındaki ilk bileşik aygıt (PNPDeviceID, hub'ın ParentIdPrefix'iyle eşleşir; kendi ParentIdPrefix'i vardır)
          • Bileşik aygıtın HID Aygıtı bölümü (PNPDeviceID, bileşik aygıtın ParentIDPrefix ile eşleşir)
        • İkinci denetleyicinin kök hub altındaki birinci hub altındaki ikinci cihaz
          • Bileşik cihazın HID Cihazı parçası
      • İkinci denetleyicinin kök hub'ı altındaki ikinci hub
        • İkinci denetleyicinin kök hub altındaki ikinci hub altındaki ilk cihaz
      • İkinci denetleyicinin kök hub'ı altındaki üçüncü hub
      • vb.
  • Sorgulandı Win32_USBController. Bu bana, aygıt ağacının en üstünde bulunan denetleyicilerimin PNPDeviceID'leri hakkında ayrıntılı bilgi verdi (bunlar önceki sorgunun Öncelleriydi). Önceki adımda türetilen ağacı kullanarak, alt öğeleri (kök hub'lar) ve alt öğeleri (diğer hub'lar) ve alt öğeleri (hub olmayan aygıtlar ve bileşik aygıtlar) ve bunların alt öğeleri vb. Üzerinde yinelemeli olarak yinelendi.
    • İlk adımda depolanan haritaya başvurarak ağacımdaki her cihaz için ayrıntılar alındı. (İsteğe bağlı olarak, Win32_PnPEntitybu adımda bilgileri almak için ilk adımı atlayabilir ve PNPDeviceId'yi kullanarak tek tek sorgulayabilir ; muhtemelen hangi sıranın daha iyi olduğunu belirleyen bir cpu-bellek değiş tokuşu.)

Özetle, Win32USBControllerDeviceBağımlılar, bir sistemdeki USB Cihazlarının tam bir listesidir (aynı sorguda Önde gelenler olan Denetleyicilerin kendileri hariç) ve bu PNPDeviceIdçiftleri kayıt defterinden ve belirtilen diğer sorgulardan gelen bilgilerle çapraz referans vererek, detaylı bir resim oluşturulabilir.


Birine 4 özdeş tarayıcı bağlı olsaydı, örneğin 4 farklı işlemde kullanılsalar hangisinin hangisi olduğunu nasıl ayırt edersiniz?
2016

2
@topshot PNPDeviceID, bağlı olduğu sürece benzersizdir. Birinin bağlantısını kesip ikinci bir özdeş olanı daha sonra bağlayıp bağlamadığınızı anlamanın bir yolu yoktur. Bu kimlik, hangi işlemin kullanıldığını umarım belirlemek için diğer alanlarda da çapraz referanslıdır.
Daniel Widdis

3
Aygıtların yerleşik seri numaraları varsa, aygıtlar farklılaştırılabilir (seri numaralarının amacı budur). Seri numarası, PnP "örnek kimliği" olarak kullanılır. Cihaz bir seri numarası içermiyorsa, örnek kimliği temelde cihaz ağacında kökten cihaza giden yoldur (ve "&" karakterlerini içerir)
Brian

Bir geri dönüş olarak, değişiklikleri izlerken her zaman cihazların listesini gözlemlemek ve fişini çekip yeniden takmak vardır.
Technophile

14

Ben ilgi cihazları görmek için, ben yerine vardı Win32_USBHubtarafından Win32_PnPEntitydayanarak, Adel Hazzah kodunda bu yazı . Bu benim için çalışıyor:

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

Bu harika çalıştı. Hangi cihazı taktığınızı belirlemeyi kolaylaştırmak için, onu belirli aralıklarla çalışacak şekilde yazın, girişleri bir sözlüğe yazın ve son çalıştırdığınızda yapılan eklemeleri rapor edin.
nixkuroi

8

Adel Hazzah en cevabı , çalışan kod verir, Daniel Widdis en ve Nedko en yorumlarınız Win32_USBControllerDevice sorgulamak ve onun Bağımlı özelliğini kullanmak gerekir ve Daniel'in söz cevabı kodu olmadan ayrıntılı bir sürü verir.

Bağlı tüm USB cihazlarının doğrudan erişilebilen PNP cihaz özelliklerini listeleyen çalışma kodunu sağlamak için yukarıdaki tartışmanın bir sentezi:

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

    }

}

İsterseniz istisna işleme eklemeniz gerekir. Aygıt ağacını ve benzerlerini anlamak istiyorsanız Daniel'in cevabına başvurun.


5

Bu, yalnızca çıkarılabilir USB sürücüleri arayan kişiler için çok daha basit bir örnektir.

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

2
Bir disket de döndürecek, muhtemelen USB kart okuyucuları, olası Zip, Jazz ve Orb sürücüleri
Mad Myche

Bu, bir USB'nin kolay adıyla eşleştirmek isteyen kişiler için ideal çözümdür. Bu örneği veri yedeklemesi için kullanıyorum ve sürücü harfi değiştiği için adı aramam gerekiyor (burada sürücü.VolumeLabel)
Bio42

4

ManagementObjectSearcher'ı şu şekilde değiştirirseniz:

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

Yani "GetUSBDevices () şuna benzer"

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

}

Sonuçlarınız USB cihazlarla sınırlı olacaktır (sisteminizdeki tüm türlerin aksine)


1
USB ile başlayan deviceID'leri arayan where cümlesi bazı öğeleri kaçırıyor. "Win32_USBControllerDevice" Bağımlılarını yinelemek daha iyidir
Daniel Widdis

2

Bu konuyu faydalı bulabilirsiniz . Ve işte bunu örnekleyen bir google kod projesi (P / Invokes into setupapi.dll).


System.Management'ı kullanmama rağmen ObjectQuery sınıfının neden bir başvurusu olmadığına dair herhangi bir fikriniz var mı?
Robert

@Robert, projeye referansı eklediniz mi? Bunu, projenizde Referanslar'a sağ tıklayarak> Referans Ekle ...> Sistem Yönetimi> Tamam'ı ara ve kontrol ederek yapabilirsiniz.
Ernest

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

bu ne yapar object value?
newbieguy

Diskteki diğer mevcut özelliklerde bir tur atın ve değerini nesne değerine kaydedin
JxDarkAngel
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.