¿Cómo puedo obtener una lista de todos los dispositivos USB conectados en una computadora con Windows?
Respuestas:
Agregue una referencia a System.Management para su proyecto, luego intente algo como esto:
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; }
}
}
Sé que estoy respondiendo a una pregunta anterior, pero acabo de realizar este mismo ejercicio y encontré un poco más de información, que creo que contribuirá mucho a la discusión y ayudará a cualquier otra persona que encuentre esta pregunta y vea dónde está las respuestas existentes se quedan cortas.
La respuesta aceptada es cercana y se puede corregir usando el comentario de Nedko . Una comprensión más detallada de las clases WMI involucradas ayuda a completar el cuadro.
Win32_USBHub
devuelve solo concentradores USB . Eso parece obvio en retrospectiva, pero la discusión anterior lo pasa por alto. No incluye todos los dispositivos USB posibles, solo aquellos que pueden (en teoría, al menos) actuar como un concentrador para dispositivos adicionales. Falta algunos dispositivos que no son concentradores (en particular, partes de dispositivos compuestos).
Win32_PnPEntity
incluye todos los dispositivos USB y cientos de dispositivos que no son USB. El consejo de Russel Gantman de usar una búsqueda de cláusula WHERE Win32_PnPEntity
para un DeviceID que comience con "USB%" para filtrar la lista es útil pero un poco incompleto; echa de menos los dispositivos bluetooth, algunas impresoras / servidores de impresión, y ratones y teclados compatibles con HID. He visto "USB \%", "USBSTOR \%", "USBPRINT \%", "BTH \%", "SWD \%" y "HID \%". Win32_PnPEntity
Sin embargo, es una buena referencia "maestra" para buscar información una vez que tenga el PNPDeviceID de otras fuentes.
Lo que encontré fue que la mejor manera de enumerar los dispositivos USB fue consultar Win32_USBControllerDevice
. Si bien no brinda información detallada para los dispositivos, enumera completamente sus dispositivos USB y le brinda un par de PNPDeviceID
s antecedente / dependiente para cada dispositivo USB (incluidos concentradores, dispositivos que no son concentradores y dispositivos compatibles con HID) en su sistema. Cada dependiente devuelto por la consulta será un dispositivo USB. El Antecedente será el Controlador al que está asignado, uno de los Controladores USB devueltos por la consulta Win32_USBController
.
Como beneficio adicional, parece que, bajo el capó, WMI recorre el árbol de dispositivos cuando responde a la Win32_USBControllerDevice
consulta, por lo que el orden en el que se devuelven estos resultados puede ayudar a identificar las relaciones entre padres e hijos. (Esto no está documentado y, por lo tanto, es solo una suposición; use CM_Get_Parent (o Child + Sibling ) de la API de SetupDi para obtener resultados definitivos). Como una opción para la API de SetupDi, parece que para todos los dispositivos enumerados a continuación Win32_USBHub
se pueden buscar en el registro (at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ + PNPDeviceID
) y tendrá un parámetro ParentIdPrefix
que será el prefijo del último campo en el PNPDeviceID de sus hijos, por lo que también podría usarse en una coincidencia comodín para filtrar la Win32_PnPEntity
consulta.
En mi aplicación, hice lo siguiente:
Win32_PnPEntity
y almacena los resultados en un mapa clave-valor (con PNPDeviceID como clave) para su posterior recuperación. Esto es opcional si desea realizar consultas individuales más adelante.Win32_USBControllerDevice
una lista definitiva de dispositivos USB en mi sistema (todos los dependientes) y extraje los PNPDeviceIDs de estos. Fui más allá, en función del orden que sigue el árbol de dispositivos, para asignar dispositivos al concentrador raíz (el primer dispositivo devuelto, en lugar del controlador) y construí un árbol basado en parentIdPrefix. El orden que devuelve la consulta, que coincide con la enumeración del árbol de dispositivos a través de SetupDi, es cada concentrador raíz (para quien el Antecedente identifica al controlador), seguido de una iteración de los dispositivos debajo de él, por ejemplo, en mi sistema:
Win32_USBController
. Esto me dio la información detallada de los PNPDeviceID de mis controladores que están en la parte superior del árbol de dispositivos (que eran los antecedentes de la consulta anterior). Utilizando el árbol derivado en el paso anterior, itera de forma recursiva sobre sus hijos (los concentradores raíz) y sus hijos (los otros concentradores) y sus hijos (dispositivos no concentradores y dispositivos compuestos) y sus hijos, etc.
Win32_PnPEntity
individualmente usando el PNPDeviceId para obtener la información en este paso; probablemente una compensación entre CPU y memoria determina qué orden es mejor).En resumen, los Win32USBControllerDevice
dependientes son una lista completa de dispositivos USB en un sistema (además de los propios controladores, que son los antecedentes en esa misma consulta), y al cruzar estos PNPDeviceId
pares con información del registro y de las otras consultas mencionadas, se puede construir una imagen detallada.
Para ver los dispositivos que me interesaban, reemplacé Win32_USBHub
por Win32_PnPEntity
en el código de Adel Hazzah, basado en esta publicación . Esto funciona para mi:
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 respuesta de Adel Hazzah proporciona un código de trabajo, los comentarios de Daniel Widdis y Nedko mencionan que debe consultar Win32_USBControllerDevice y usar su propiedad Dependiente, y la respuesta de Daniel brinda muchos detalles sin código.
Aquí hay una síntesis de la discusión anterior para proporcionar un código de trabajo que enumere las propiedades del dispositivo PNP directamente accesibles de todos los dispositivos USB conectados:
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;
}
}
}
Deberá agregar el manejo de excepciones si lo desea. Consulte la respuesta de Daniel si desea averiguar el árbol de dispositivos y demás.
Este es un ejemplo mucho más simple para las personas que solo buscan unidades USB extraíbles.
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 cambia ManagementObjectSearcher a lo siguiente:
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
@"SELECT * FROM Win32_PnPEntity where DeviceID Like ""USB%""");
Entonces, "GetUSBDevices () se ve así"
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;
}
}
Sus resultados se limitarán a dispositivos USB (a diferencia de todos los tipos de su sistema)
Puede encontrar este hilo útil. Y aquí hay un proyecto de código de Google que ejemplifica esto (P / Invoca en 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
?