Bagaimana saya bisa mendapatkan daftar semua perangkat USB yang terhubung di komputer windows?
Jawaban:
Tambahkan referensi ke System.Management untuk proyek Anda, lalu coba sesuatu seperti ini:
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; }
}
}
Saya tahu saya menjawab pertanyaan lama, tetapi saya baru saja melakukan latihan yang sama dan menemukan sedikit lebih banyak informasi, yang menurut saya akan berkontribusi banyak pada diskusi dan membantu siapa pun yang menemukan pertanyaan ini dan melihat di mana jawaban yang ada gagal.
The jawaban yang diterima dekat, dan dapat diperbaiki menggunakan komentar Nedko ini untuk itu. Pemahaman yang lebih rinci tentang Kelas WMI yang terlibat membantu melengkapi gambaran tersebut.
Win32_USBHub
hanya mengembalikan Hub USB . Tampaknya sudah jelas di belakang, tetapi pembahasan di atas meleset. Ini tidak mencakup semua perangkat USB yang memungkinkan, hanya yang dapat (setidaknya secara teori) bertindak sebagai hub untuk perangkat tambahan. Ini merindukan beberapa perangkat yang bukan hub (terutama bagian dari perangkat komposit).
Win32_PnPEntity
tidak mencakup semua perangkat USB, dan ratusan perangkat non-USB lainnya. Saran Russel Gantman untuk menggunakan pencarian klausa WHERE Win32_PnPEntity
untuk DeviceID yang diawali dengan "USB%" untuk memfilter daftar sangat membantu tetapi sedikit tidak lengkap; itu merindukan perangkat bluetooth, beberapa printer / server cetak, dan mouse dan keyboard yang sesuai dengan HID. Saya telah melihat "USB \%", "USBSTOR \%", "USBPRINT \%", "BTH \%", "SWD \%", dan "HID \%". Win32_PnPEntity
adalah, bagaimanapun, referensi "master" yang baik untuk mencari informasi setelah Anda memiliki PNPDeviceID dari sumber lain.
Apa yang saya temukan adalah cara terbaik untuk menghitung perangkat USB adalah dengan menanyakannya Win32_USBControllerDevice
. Meskipun tidak memberikan informasi terperinci untuk perangkat, itu benar-benar menghitung perangkat USB Anda dan memberi Anda pasangan Anteseden / Tergantung PNPDeviceID
untuk setiap Perangkat USB (termasuk Hub, perangkat non-Hub, dan perangkat yang kompatibel dengan HID) pada perangkat Anda. sistem. Setiap Dependen yang dikembalikan dari kueri akan menjadi Perangkat USB. Anteseden akan menjadi Pengontrol yang ditetapkan, salah satu Pengontrol USB yang dikembalikan dengan melakukan kueri Win32_USBController
.
Sebagai bonus, tampak bahwa di bawah tenda, WMI berjalan di Pohon Perangkat saat menanggapi Win32_USBControllerDevice
kueri, sehingga urutan hasil ini dikembalikan dapat membantu mengidentifikasi hubungan induk / anak. (Ini tidak didokumentasikan dan karenanya hanya tebakan; gunakan CM_Get_Parent (atau Child + Sibling ) SetupDi API untuk hasil yang pasti.) Sebagai opsi untuk SetupDi API, tampaknya untuk semua perangkat yang terdaftar di bawahnya Win32_USBHub
dapat dicari di registri (at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ + PNPDeviceID
) dan akan memiliki parameter ParentIdPrefix
yang akan menjadi awalan bidang terakhir di PNPDeviceID anak-anaknya, jadi ini juga bisa digunakan dalam pertandingan karakter pengganti untuk memfilter Win32_PnPEntity
kueri.
Dalam lamaran saya, saya melakukan hal berikut:
Win32_PnPEntity
dan menyimpan hasil dalam peta nilai kunci (dengan PNPDeviceID sebagai kunci) untuk pengambilan nanti. Ini opsional jika Anda ingin melakukan kueri individual nanti.Win32_USBControllerDevice
untuk daftar definitif perangkat USB di sistem saya (semua Dependen) dan mengekstrak PNPDeviceIDs ini. Saya melangkah lebih jauh, berdasarkan urutan mengikuti pohon perangkat, untuk menetapkan perangkat ke hub akar (perangkat pertama dikembalikan, bukan pengontrol) dan membangun pohon berdasarkan parentIdPrefix. Urutan yang dikembalikan kueri, yang cocok dengan enumerasi pohon perangkat melalui SetupDi, adalah masing-masing hub root (untuk siapa Anteseden mengidentifikasi pengontrol), diikuti dengan iterasi perangkat di bawahnya, misalnya, di sistem saya:
Win32_USBController
. Ini memberi saya informasi rinci tentang PNPDeviceIDs dari pengontrol saya yang ada di bagian atas pohon perangkat (yang merupakan Anteseden dari kueri sebelumnya). Menggunakan pohon yang diturunkan pada langkah sebelumnya, secara rekursif melakukan iterasi terhadap turunannya (hub root) dan turunannya (hub lain) dan turunannya (perangkat non-hub dan perangkat komposit) dan turunannya, dll.
Win32_PnPEntity
per satu menggunakan PNPDeviceId untuk mendapatkan informasi pada langkah ini; mungkin tradeoff cpu vs. memori menentukan urutan mana yang lebih baik.)Singkatnya, Win32USBControllerDevice
Dependen adalah daftar lengkap Perangkat USB pada sistem (selain Pengontrol itu sendiri, yang merupakan Anteseden dalam kueri yang sama), dan dengan mereferensikan PNPDeviceId
pasangan ini dengan informasi dari registri dan dari kueri lain yang disebutkan, gambaran rinci dapat dibuat.
Untuk melihat device yang saya minati, saya telah menggantinya Win32_USBHub
dengan Win32_PnPEntity
kode Adel Hazzah, berdasarkan postingan ini . Ini bekerja untuk saya:
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 ini jawaban memberi kode bekerja, Daniel Widdis ini dan Nedko ini komentar menyebutkan bahwa Anda perlu query Win32_USBControllerDevice dan menggunakan properti Dependent nya, dan Daniel jawaban memberikan banyak detail tanpa kode.
Berikut adalah sintesis dari pembahasan di atas untuk memberikan kode kerja yang mencantumkan properti perangkat PNP yang dapat diakses langsung dari semua perangkat USB yang terhubung:
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;
}
}
}
Anda harus menambahkan penanganan pengecualian jika Anda menginginkannya. Konsultasikan jawaban Daniel jika Anda ingin mengetahui pohon perangkat dan semacamnya.
Ini adalah contoh yang jauh lebih sederhana untuk orang yang hanya mencari drive usb yang dapat dilepas.
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));
}
}
Jika Anda mengubah ManagementObjectSearcher sebagai berikut:
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
@"SELECT * FROM Win32_PnPEntity where DeviceID Like ""USB%""");
Jadi "GetUSBDevices () terlihat seperti ini"
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;
}
}
Hasil Anda akan terbatas pada perangkat USB (berbeda dengan semua jenis di sistem Anda)
Anda mungkin menemukan utas ini berguna. Dan inilah proyek kode google yang mencontohkan ini (P / Memanggil ke 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
?