Respostas:
Adicione uma referência a System.Management para seu projeto e, em seguida, tente algo assim:
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; }
}
}
Sei que estou respondendo a uma pergunta antiga, mas acabei de fazer esse mesmo exercício e descobri um pouco mais de informações, que acho que vão contribuir muito para a discussão e ajudar qualquer pessoa que encontrar essa pergunta e ver onde o as respostas existentes ficam aquém.
A resposta aceita é aproximada e pode ser corrigida usando o comentário de Nedko . Uma compreensão mais detalhada das classes WMI envolvidas ajuda a completar o quadro.
Win32_USBHub
retorna apenas Hubs USB . Isso parece óbvio em retrospectiva, mas a discussão acima não percebe. Não inclui todos os dispositivos USB possíveis, apenas aqueles que podem (pelo menos em teoria) funcionar como um hub para dispositivos adicionais. Ele perde alguns dispositivos que não são hubs (particularmente partes de dispositivos compostos).
Win32_PnPEntity
inclui todos os dispositivos USB e centenas de outros dispositivos não USB. O conselho de Russel Gantman de usar uma cláusula WHERE Win32_PnPEntity
para procurar um DeviceID começando com "USB%" para filtrar a lista é útil, mas um pouco incompleto; falta dispositivos bluetooth, algumas impressoras / servidores de impressão e mouses e teclados compatíveis com HID. Eu vi "USB \%", "USBSTOR \%", "USBPRINT \%", "BTH \%", "SWD \%" e "HID \%". Win32_PnPEntity
é, no entanto, uma boa referência "mestre" para pesquisar informações, uma vez que você tenha o PNPDeviceID de outras fontes.
O que descobri foi que a melhor maneira de enumerar os dispositivos USB foi por meio de consulta Win32_USBControllerDevice
. Embora não forneça informações detalhadas para os dispositivos, ele enumera completamente seus dispositivos USB e fornece um par de antecedentes / dependentes PNPDeviceID
para cada dispositivo USB (incluindo hubs, dispositivos não Hub e dispositivos compatíveis com HID) em seu sistema. Cada Dependente retornado da consulta será um Dispositivo USB. O Antecedente será o Controlador ao qual está atribuído, um dos Controladores USB retornados pela consulta Win32_USBController
.
Como um bônus, parece que, nos bastidores, o WMI percorre a Árvore de Dispositivos ao responder à Win32_USBControllerDevice
consulta, portanto, a ordem em que esses resultados são retornados pode ajudar a identificar as relações pai / filho. (Isso não está documentado e, portanto, é apenas uma suposição; use CM_Get_Parent da API SetupDi (ou Child + Sibling ) para resultados definitivos.) Como uma opção para a API SetupDi, parece que para todos os dispositivos listados em Win32_USBHub
eles podem ser consultados no registro (at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ + PNPDeviceID
) e terá um parâmetro ParentIdPrefix
que será o prefixo do último campo no PNPDeviceID de seus filhos, de forma que também poderá ser usado em uma correspondência curinga para filtrar a Win32_PnPEntity
consulta.
Em meu aplicativo, fiz o seguinte:
Win32_PnPEntity
e armazenado os resultados em um mapa de valor-chave (com PNPDeviceID como a chave) para recuperação posterior. Isso é opcional se você quiser fazer consultas individuais posteriormente.Win32_USBControllerDevice
uma lista definitiva de dispositivos USB em meu sistema (todos os dependentes) e extraí os PNPDeviceIDs deles. Fui além, com base na ordem seguindo a árvore de dispositivos, para atribuir dispositivos ao hub raiz (o primeiro dispositivo retornado, em vez do controlador) e construí uma árvore baseada no parentIdPrefix. A ordem que a consulta retorna, que corresponde à enumeração da árvore de dispositivos via SetupDi, é cada hub raiz (para quem o Antecedente identifica o controlador), seguido por uma iteração de dispositivos sob ele, por exemplo, no meu sistema:
Win32_USBController
. Isso me deu informações detalhadas dos PNPDeviceIDs dos meus controladores que estão no topo da árvore de dispositivos (que eram os antecedentes da consulta anterior). Usando a árvore derivada na etapa anterior, iterou recursivamente sobre seus filhos (os hubs raiz) e seus filhos (os outros hubs) e seus filhos (dispositivos não hub e dispositivos compostos) e seus filhos, etc.
Win32_PnPEntity
individualmente usando o PNPDeviceId para obter as informações nesta etapa; provavelmente uma compensação de CPU x memória determinando qual pedido é melhor.)Em resumo, os Win32USBControllerDevice
Dependentes são uma lista completa de Dispositivos USB em um sistema (além dos próprios Controladores, que são os Antecedentes nessa mesma consulta), e por referência cruzada desses PNPDeviceId
pares com informações do registro e de outras consultas mencionadas, uma imagem detalhada pode ser construída.
Para ver os dispositivos que me interessavam, substituí Win32_USBHub
por Win32_PnPEntity
no código de Adel Hazzah, com base neste post . Isso funciona para mim:
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; }
}
}
A resposta de Adel Hazzah fornece código funcional, os comentários de Daniel Widdis e Nedko mencionam que você precisa consultar Win32_USBControllerDevice e usar sua propriedade Dependent, e a resposta de Daniel fornece muitos detalhes sem código.
Aqui está uma síntese da discussão acima para fornecer um código de trabalho que lista as propriedades do dispositivo PNP diretamente acessíveis de todos os 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;
}
}
}
Você precisará adicionar tratamento de exceções, se quiser. Consulte a resposta de Daniel se você quiser descobrir a árvore de dispositivos e tal.
Este é um exemplo muito mais simples para pessoas que procuram apenas unidades USB removíveis.
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));
}
}
Se você alterar o ManagementObjectSearcher para o seguinte:
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
@"SELECT * FROM Win32_PnPEntity where DeviceID Like ""USB%""");
Portanto, o "GetUSBDevices () se parece com isto"
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;
}
}
Seus resultados serão limitados a dispositivos USB (ao contrário de todos os tipos em seu sistema)
Você pode achar este tópico útil. E aqui está um projeto de código do Google exemplificando isso (ele P / Invoca em 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
faz?