C# Usb设备信息枚举总结
背景
如果需要做Usb相关的开发,需要通过代码取得Usb设备在设备管理器中的各项信息,就需要对Usb设备信息进行枚举。
C++的相关方法
Usb设备信息的C++枚举方法在msdn上可以简单的查询到。不特别说明,下面贴出参考方法
reference:https://stackoverflow.com/questions/3438366/setupdigetdeviceproperty-usage-example?lq=1
#include
#include // for GUID_DEVCLASS_CDROM etc
#include
#include // for MAX_DEVICE_ID_LEN, CM_Get_Parent and CM_Get_Device_ID
#define INITGUID
#include
#include
//#include "c:\WinDDK\7600.16385.1\inc\api\devpkey.h"
// include DEVPKEY_Device_BusReportedDeviceDesc from WinDDK\7600.16385.1\inc\api\devpropdef.h
#ifdef DEFINE_DEVPROPKEY
#undef DEFINE_DEVPROPKEY
#endif
#ifdef INITGUID
#define DEFINE_DEVPROPKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) EXTERN_C const DEVPROPKEY DECLSPEC_SELECTANY name = { { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }, pid }
#else
#define DEFINE_DEVPROPKEY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, pid) EXTERN_C const DEVPROPKEY name
#endif // INITGUID
// include DEVPKEY_Device_BusReportedDeviceDesc from WinDDK\7600.16385.1\inc\api\devpkey.h
DEFINE_DEVPROPKEY(DEVPKEY_Device_BusReportedDeviceDesc, 0x540b947e, 0x8b40, 0x45bc, 0xa8, 0xa2, 0x6a, 0x0b, 0x89, 0x4c, 0xbd, 0xa2, 4); // DEVPROP_TYPE_STRING
DEFINE_DEVPROPKEY(DEVPKEY_Device_ContainerId, 0x8c7ed206, 0x3f8a, 0x4827, 0xb3, 0xab, 0xae, 0x9e, 0x1f, 0xae, 0xfc, 0x6c, 2); // DEVPROP_TYPE_GUID
DEFINE_DEVPROPKEY(DEVPKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14); // DEVPROP_TYPE_STRING
DEFINE_DEVPROPKEY(DEVPKEY_DeviceDisplay_Category, 0x78c34fc8, 0x104a, 0x4aca, 0x9e, 0xa4, 0x52, 0x4d, 0x52, 0x99, 0x6e, 0x57, 0x5a); // DEVPROP_TYPE_STRING_LIST
DEFINE_DEVPROPKEY(DEVPKEY_Device_LocationInfo, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 15); // DEVPROP_TYPE_STRING
DEFINE_DEVPROPKEY(DEVPKEY_Device_Manufacturer, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 13); // DEVPROP_TYPE_STRING
DEFINE_DEVPROPKEY(DEVPKEY_Device_SecuritySDS, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 26); // DEVPROP_TYPE_SECURITY_DESCRIPTOR_STRING
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
#pragma comment (lib, "setupapi.lib")
typedef BOOL(WINAPI *FN_SetupDiGetDevicePropertyW)(
__in HDEVINFO DeviceInfoSet,
__in PSP_DEVINFO_DATA DeviceInfoData,
__in const DEVPROPKEY *PropertyKey,
__out DEVPROPTYPE *PropertyType,
__out_opt PBYTE PropertyBuffer,
__in DWORD PropertyBufferSize,
__out_opt PDWORD RequiredSize,
__in DWORD Flags
);
// List all USB devices with some additional information
void ListDevices(CONST GUID *pClassGuid, LPCTSTR pszEnumerator)
{
unsigned i, j;
DWORD dwSize, dwPropertyRegDataType;
DEVPROPTYPE ulPropertyType;
CONFIGRET status;
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData;
const static LPCTSTR arPrefix[3] = { TEXT("VID_"), TEXT("PID_"), TEXT("MI_") };
TCHAR szDeviceInstanceID[MAX_DEVICE_ID_LEN];
TCHAR szDesc[1024], szHardwareIDs[4096];
WCHAR szBuffer[4096];
LPTSTR pszToken, pszNextToken;
TCHAR szVid[MAX_DEVICE_ID_LEN], szPid[MAX_DEVICE_ID_LEN], szMi[MAX_DEVICE_ID_LEN];
FN_SetupDiGetDevicePropertyW fn_SetupDiGetDevicePropertyW = (FN_SetupDiGetDevicePropertyW)
GetProcAddress(GetModuleHandle(TEXT("Setupapi.dll")), "SetupDiGetDevicePropertyW");
// List all connected USB devices
hDevInfo = SetupDiGetClassDevs(pClassGuid, pszEnumerator, NULL,
pClassGuid != NULL ? DIGCF_PRESENT : DIGCF_ALLCLASSES | DIGCF_PRESENT);
if (hDevInfo == INVALID_HANDLE_VALUE)
return;
// Find the ones that are driverless
for (i = 0; ; i++) {
DeviceInfoData.cbSize = sizeof(DeviceInfoData);
if (!SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData))
break;
status = CM_Get_Device_ID(DeviceInfoData.DevInst, szDeviceInstanceID, MAX_PATH, 0);
if (status != CR_SUCCESS)
continue;
// Display device instance ID
_tprintf(TEXT("%s\n"), szDeviceInstanceID);
if (SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC,
&dwPropertyRegDataType, (BYTE*)szDesc,
sizeof(szDesc), // The size, in bytes
&dwSize))
_tprintf(TEXT(" Device Description: \"%s\"\n"), szDesc);
if (SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_HARDWAREID,
&dwPropertyRegDataType, (BYTE*)szHardwareIDs,
sizeof(szHardwareIDs), // The size, in bytes
&dwSize)) {
LPCTSTR pszId;
_tprintf(TEXT(" Hardware IDs:\n"));
for (pszId = szHardwareIDs;
*pszId != TEXT('\0') && pszId + dwSize / sizeof(TCHAR) <= szHardwareIDs + ARRAYSIZE(szHardwareIDs);
pszId += lstrlen(pszId) + 1) {
_tprintf(TEXT(" \"%s\"\n"), pszId);
}
}
// Retreive the device description as reported by the device itself
// On Vista and earlier, we can use only SPDRP_DEVICEDESC
// On Windows 7, the information we want ("Bus reported device description") is
// accessed through DEVPKEY_Device_BusReportedDeviceDesc
if (fn_SetupDiGetDevicePropertyW && fn_SetupDiGetDevicePropertyW(hDevInfo, &DeviceInfoData, &DEVPKEY_Device_BusReportedDeviceDesc,
&ulPropertyType, (BYTE*)szBuffer, sizeof(szBuffer), &dwSize, 0)) {
if (fn_SetupDiGetDevicePropertyW(hDevInfo, &DeviceInfoData, &DEVPKEY_Device_BusReportedDeviceDesc,
&ulPropertyType, (BYTE*)szBuffer, sizeof(szBuffer), &dwSize, 0))
_tprintf(TEXT(" Bus Reported Device Description: \"%ls\"\n"), szBuffer);
if (fn_SetupDiGetDevicePropertyW(hDevInfo, &DeviceInfoData, &DEVPKEY_Device_Manufacturer,
&ulPropertyType, (BYTE*)szBuffer, sizeof(szBuffer), &dwSize, 0)) {
_tprintf(TEXT(" Device Manufacturer: \"%ls\"\n"), szBuffer);
}
if (fn_SetupDiGetDevicePropertyW(hDevInfo, &DeviceInfoData, &DEVPKEY_Device_FriendlyName,
&ulPropertyType, (BYTE*)szBuffer, sizeof(szBuffer), &dwSize, 0)) {
_tprintf(TEXT(" Device Friendly Name: \"%ls\"\n"), szBuffer);
}
if (fn_SetupDiGetDevicePropertyW(hDevInfo, &DeviceInfoData, &DEVPKEY_Device_LocationInfo,
&ulPropertyType, (BYTE*)szBuffer, sizeof(szBuffer), &dwSize, 0)) {
_tprintf(TEXT(" Device Location Info: \"%ls\"\n"), szBuffer);
}
if (fn_SetupDiGetDevicePropertyW(hDevInfo, &DeviceInfoData, &DEVPKEY_Device_SecuritySDS,
&ulPropertyType, (BYTE*)szBuffer, sizeof(szBuffer), &dwSize, 0)) {
// See Security Descriptor Definition Language on MSDN
// (http://msdn.microsoft.com/en-us/library/windows/desktop/aa379567(v=vs.85).aspx)
_tprintf(TEXT(" Device Security Descriptor String: \"%ls\"\n"), szBuffer);
}
if (fn_SetupDiGetDevicePropertyW(hDevInfo, &DeviceInfoData, &DEVPKEY_Device_ContainerId,
&ulPropertyType, (BYTE*)szDesc, sizeof(szDesc), &dwSize, 0)) {
StringFromGUID2((REFGUID)szDesc, szBuffer, ARRAY_SIZE(szBuffer));
_tprintf(TEXT(" ContainerId: \"%ls\"\n"), szBuffer);
}
if (fn_SetupDiGetDevicePropertyW(hDevInfo, &DeviceInfoData, &DEVPKEY_DeviceDisplay_Category,
&ulPropertyType, (BYTE*)szBuffer, sizeof(szBuffer), &dwSize, 0))
_tprintf(TEXT(" Device Display Category: \"%ls\"\n"), szBuffer);
}
pszToken = _tcstok_s(szDeviceInstanceID, TEXT("\\#&"), &pszNextToken);
while (pszToken != NULL) {
szVid[0] = TEXT('\0');
szPid[0] = TEXT('\0');
szMi[0] = TEXT('\0');
for (j = 0; j < 3; j++) {
if (_tcsncmp(pszToken, arPrefix[j], lstrlen(arPrefix[j])) == 0) {
switch (j) {
case 0:
_tcscpy_s(szVid, ARRAY_SIZE(szVid), pszToken);
break;
case 1:
_tcscpy_s(szPid, ARRAY_SIZE(szPid), pszToken);
break;
case 2:
_tcscpy_s(szMi, ARRAY_SIZE(szMi), pszToken);
break;
default:
break;
}
}
}
if (szVid[0] != TEXT('\0'))
_tprintf(TEXT(" vid: \"%s\"\n"), szVid);
if (szPid[0] != TEXT('\0'))
_tprintf(TEXT(" pid: \"%s\"\n"), szPid);
if (szMi[0] != TEXT('\0'))
_tprintf(TEXT(" mi: \"%s\"\n"), szMi);
pszToken = _tcstok_s(NULL, TEXT("\\#&"), &pszNextToken);
}
}
return;
}
int _tmain()
{
// List all connected USB devices
_tprintf(TEXT("---------------\n"));
_tprintf(TEXT("- USB devices -\n"));
_tprintf(TEXT("---------------\n"));
ListDevices(NULL, TEXT("USB"));
_tprintf(TEXT("\n"));
_tprintf(TEXT("-------------------\n"));
_tprintf(TEXT("- USBSTOR devices -\n"));
_tprintf(TEXT("-------------------\n"));
ListDevices(NULL, TEXT("USBSTOR"));
_tprintf(TEXT("\n"));
_tprintf(TEXT("--------------\n"));
_tprintf(TEXT("- SD devices -\n"));
_tprintf(TEXT("--------------\n"));
ListDevices(NULL, TEXT("SD"));
//_tprintf (TEXT("\n"));
//ListDevices(&GUID_DEVCLASS_USB, NULL);
//_tprintf (TEXT("\n"));
_tprintf(TEXT("\n"));
_tprintf(TEXT("-----------\n"));
_tprintf(TEXT("- Volumes -\n"));
_tprintf(TEXT("-----------\n"));
//ListDevices(NULL, TEXT("STORAGE\\VOLUME"));
//_tprintf (TEXT("\n"));
ListDevices(&GUID_DEVCLASS_VOLUME, NULL);
_tprintf(TEXT("\n"));
_tprintf(TEXT("----------------------------\n"));
_tprintf(TEXT("- devices with disk drives -\n"));
_tprintf(TEXT("----------------------------\n"));
ListDevices(&GUID_DEVCLASS_DISKDRIVE, NULL);
return 0;
}
C# wmi枚举方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace UltraMon.USBInfos
{
///
/// 即插即用设备信息结构
///
public struct PnPEntityInfo
{
public String PNPDeviceID; // 设备ID
public String Name; // 设备名称
public String Description; // 设备描述
public String Service; // 服务
public String Status; // 设备状态
public UInt16 VendorID; // 供应商标识
public UInt16 ProductID; // 产品编号
public Guid ClassGuid; // 设备安装类GUID
}
///
/// 基于WMI获取USB设备信息
///
public partial class USB
{
#region UsbDevice
///
/// 获取所有的USB设备实体(过滤没有VID和PID的设备)
///
public static PnPEntityInfo[] AllUsbDevices
{
get
{
return WhoUsbDevice(UInt16.MinValue, UInt16.MinValue, Guid.Empty);
}
}
///
/// 查询USB设备实体(设备要求有VID和PID)
///
/// 供应商标识,MinValue忽视
/// 产品编号,MinValue忽视
/// 设备安装类Guid,Empty忽视
/// 设备列表
public static PnPEntityInfo[] WhoUsbDevice(UInt16 VendorID, UInt16 ProductID, Guid ClassGuid)
{
List UsbDevices = new List();
// 获取USB控制器及其相关联的设备实体
ManagementObjectCollection USBControllerDeviceCollection = new ManagementObjectSearcher("SELECT * FROM Win32_USBControllerDevice").Get();
if (USBControllerDeviceCollection != null)
{
foreach (ManagementObject USBControllerDevice in USBControllerDeviceCollection)
{ // 获取设备实体的DeviceID
String Dependent = (USBControllerDevice["Dependent"] as String).Split(new Char[] { '=' })[1];
// 过滤掉没有VID和PID的USB设备
Match match = Regex.Match(Dependent, "VID_[0-9|A-F]{4}&PID_[0-9|A-F]{4}");
if (match.Success)
{
UInt16 theVendorID = Convert.ToUInt16(match.Value.Substring(4, 4), 16); // 供应商标识
if (VendorID != UInt16.MinValue && VendorID != theVendorID) continue;
UInt16 theProductID = Convert.ToUInt16(match.Value.Substring(13, 4), 16); // 产品编号
if (ProductID != UInt16.MinValue && ProductID != theProductID) continue;
ManagementObjectCollection PnPEntityCollection = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity WHERE DeviceID=" + Dependent).Get();
if (PnPEntityCollection != null)
{
foreach (ManagementObject Entity in PnPEntityCollection)
{
Guid theClassGuid = new Guid(Entity["ClassGuid"] as String); // 设备安装类GUID
if (ClassGuid != Guid.Empty && ClassGuid != theClassGuid) continue;
PnPEntityInfo Element;
Element.PNPDeviceID = Entity["PNPDeviceID"] as String; // 设备ID
Element.Name = Entity["Name"] as String; // 设备名称
Element.Description = Entity["Description"] as String; // 设备描述
Element.Service = Entity["Service"] as String; // 服务
Element.Status = Entity["Status"] as String; // 设备状态
Element.VendorID = theVendorID; // 供应商标识
Element.ProductID = theProductID; // 产品编号
Element.ClassGuid = theClassGuid; // 设备安装类GUID
UsbDevices.Add(Element);
}
}
}
}
}
if (UsbDevices.Count == 0) return null; else return UsbDevices.ToArray();
}
///
/// 查询USB设备实体(设备要求有VID和PID)
///
/// 供应商标识,MinValue忽视
/// 产品编号,MinValue忽视
/// 设备列表
public static PnPEntityInfo[] WhoUsbDevice(UInt16 VendorID, UInt16 ProductID)
{
return WhoUsbDevice(VendorID, ProductID, Guid.Empty);
}
///
/// 查询USB设备实体(设备要求有VID和PID)
///
/// 设备安装类Guid,Empty忽视
/// 设备列表
public static PnPEntityInfo[] WhoUsbDevice(Guid ClassGuid)
{
return WhoUsbDevice(UInt16.MinValue, UInt16.MinValue, ClassGuid);
}
///
/// 查询USB设备实体(设备要求有VID和PID)
///
/// 设备ID,可以是不完整信息
/// 设备列表
public static PnPEntityInfo[] WhoUsbDevice(String PNPDeviceID)
{
List UsbDevices = new List();
// 获取USB控制器及其相关联的设备实体
ManagementObjectCollection USBControllerDeviceCollection = new ManagementObjectSearcher("SELECT * FROM Win32_USBControllerDevice").Get();
if (USBControllerDeviceCollection != null)
{
foreach (ManagementObject USBControllerDevice in USBControllerDeviceCollection)
{ // 获取设备实体的DeviceID
String Dependent = (USBControllerDevice["Dependent"] as String).Split(new Char[] { '=' })[1];
if (!String.IsNullOrEmpty(PNPDeviceID))
{ // 注意:忽视大小写
if (Dependent.IndexOf(PNPDeviceID, 1, PNPDeviceID.Length - 2, StringComparison.OrdinalIgnoreCase) == -1) continue;
}
// 过滤掉没有VID和PID的USB设备
Match match = Regex.Match(Dependent, "VID_[0-9|A-F]{4}&PID_[0-9|A-F]{4}");
if (match.Success)
{
ManagementObjectCollection PnPEntityCollection = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity WHERE DeviceID=" + Dependent).Get();
if (PnPEntityCollection != null)
{
foreach (ManagementObject Entity in PnPEntityCollection)
{
PnPEntityInfo Element;
Element.PNPDeviceID = Entity["PNPDeviceID"] as String; // 设备ID
Element.Name = Entity["Name"] as String; // 设备名称
Element.Description = Entity["Description"] as String; // 设备描述
Element.Service = Entity["Service"] as String; // 服务
Element.Status = Entity["Status"] as String; // 设备状态
Element.VendorID = Convert.ToUInt16(match.Value.Substring(4, 4), 16); // 供应商标识
Element.ProductID = Convert.ToUInt16(match.Value.Substring(13, 4), 16); // 产品编号 // 产品编号
Element.ClassGuid = new Guid(Entity["ClassGuid"] as String); // 设备安装类GUID
UsbDevices.Add(Element);
}
}
}
}
}
if (UsbDevices.Count == 0) return null; else return UsbDevices.ToArray();
}
///
/// 根据服务定位USB设备
///
/// 要查询的服务集合
/// 设备列表
public static PnPEntityInfo[] WhoUsbDevice(String[] ServiceCollection)
{
if (ServiceCollection == null || ServiceCollection.Length == 0)
return WhoUsbDevice(UInt16.MinValue, UInt16.MinValue, Guid.Empty);
List UsbDevices = new List();
// 获取USB控制器及其相关联的设备实体
ManagementObjectCollection USBControllerDeviceCollection = new ManagementObjectSearcher("SELECT * FROM Win32_USBControllerDevice").Get();
if (USBControllerDeviceCollection != null)
{
foreach (ManagementObject USBControllerDevice in USBControllerDeviceCollection)
{ // 获取设备实体的DeviceID
String Dependent = (USBControllerDevice["Dependent"] as String).Split(new Char[] { '=' })[1];
// 过滤掉没有VID和PID的USB设备
Match match = Regex.Match(Dependent, "VID_[0-9|A-F]{4}&PID_[0-9|A-F]{4}");
if (match.Success)
{
ManagementObjectCollection PnPEntityCollection = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity WHERE DeviceID=" + Dependent).Get();
if (PnPEntityCollection != null)
{
foreach (ManagementObject Entity in PnPEntityCollection)
{
String theService = Entity["Service"] as String; // 服务
if (String.IsNullOrEmpty(theService)) continue;
foreach (String Service in ServiceCollection)
{ // 注意:忽视大小写
if (String.Compare(theService, Service, true) != 0) continue;
PnPEntityInfo Element;
Element.PNPDeviceID = Entity["PNPDeviceID"] as String; // 设备ID
Element.Name = Entity["Name"] as String; // 设备名称
Element.Description = Entity["Description"] as String; // 设备描述
Element.Service = theService; // 服务
Element.Status = Entity["Status"] as String; // 设备状态
Element.VendorID = Convert.ToUInt16(match.Value.Substring(4, 4), 16); // 供应商标识
Element.ProductID = Convert.ToUInt16(match.Value.Substring(13, 4), 16); // 产品编号
Element.ClassGuid = new Guid(Entity["ClassGuid"] as String); // 设备安装类GUID
UsbDevices.Add(Element);
break;
}
}
}
}
}
}
if (UsbDevices.Count == 0) return null; else return UsbDevices.ToArray();
}
#endregion
#region PnPEntity
///
/// 所有即插即用设备实体(过滤没有VID和PID的设备)
///
public static PnPEntityInfo[] AllPnPEntities
{
get
{
return WhoPnPEntity(UInt16.MinValue, UInt16.MinValue, Guid.Empty);
}
}
///
/// 根据VID和PID及设备安装类GUID定位即插即用设备实体
///
/// 供应商标识,MinValue忽视
/// 产品编号,MinValue忽视
/// 设备安装类Guid,Empty忽视
/// 设备列表
///
/// HID:{745a17a0-74d3-11d0-b6fe-00a0c90f57da}
/// Imaging Device:{6bdd1fc6-810f-11d0-bec7-08002be2092f}
/// Keyboard:{4d36e96b-e325-11ce-bfc1-08002be10318}
/// Mouse:{4d36e96f-e325-11ce-bfc1-08002be10318}
/// Network Adapter:{4d36e972-e325-11ce-bfc1-08002be10318}
/// USB:{36fc9e60-c465-11cf-8056-444553540000}
///
public static PnPEntityInfo[] WhoPnPEntity(UInt16 VendorID, UInt16 ProductID, Guid ClassGuid)
{
List PnPEntities = new List();
// 枚举即插即用设备实体
String VIDPID;
if (VendorID == UInt16.MinValue)
{
if (ProductID == UInt16.MinValue)
VIDPID = "'%VID[_]____&PID[_]____%'";
else
VIDPID = "'%VID[_]____&PID[_]" + ProductID.ToString("X4") + "%'";
}
else
{
if (ProductID == UInt16.MinValue)
VIDPID = "'%VID[_]" + VendorID.ToString("X4") + "&PID[_]____%'";
else
VIDPID = "'%VID[_]" + VendorID.ToString("X4") + "&PID[_]" + ProductID.ToString("X4") + "%'";
}
String QueryString;
if (ClassGuid == Guid.Empty)
QueryString = "SELECT * FROM Win32_PnPEntity WHERE PNPDeviceID LIKE" + VIDPID;
else
QueryString = "SELECT * FROM Win32_PnPEntity WHERE PNPDeviceID LIKE" + VIDPID + " AND ClassGuid='" + ClassGuid.ToString("B") + "'";
PropertyDataCollection propertyDataCollection ;
bool toShow = false;
ManagementObjectCollection PnPEntityCollection = new ManagementObjectSearcher(QueryString).Get();
if (PnPEntityCollection != null)
{
foreach (ManagementObject Entity in PnPEntityCollection)
{
propertyDataCollection = Entity.Properties;
String PNPDeviceID = Entity["PNPDeviceID"] as String;
Match match = Regex.Match(PNPDeviceID, "VID_[0-9|A-F]{4}&PID_[0-9|A-F]{4}");
if (match.Success)
{
PnPEntityInfo Element;
Element.PNPDeviceID = PNPDeviceID; // 设备ID
var cs = Entity.Properties;
foreach (var c in cs)
{
//Console.WriteLine(c.Value);
//Console.WriteLine(c.Name);
if (c.Name != null && c.Value != null)
{
if (c.Name.Contains("DN2SKRKU") || c.Value.ToString().Contains("DN2SKRKU"))
{
propertyDataCollection = cs;
toShow = true;
Console.WriteLine("+++++++++++++++++++++++++++++++++++++++++++++++++++++++");
}
}
//Console.WriteLine("-----------------------------------------");
}
if (toShow)
{
Console.WriteLine("----------toshow {0}",toShow);
foreach (var c in propertyDataCollection)
{
Console.WriteLine(c.Value);
Console.WriteLine(c.Name);
Console.WriteLine("++");
}
toShow = false;
}
Element.Name = Entity["Name"] as String; // 设备名称
Element.Description = Entity["Description"] as String; // 设备描述
Element.Service = Entity["Service"] as String; // 服务
Element.Status = Entity["Status"] as String; // 设备状态
Element.VendorID = Convert.ToUInt16(match.Value.Substring(4, 4), 16); // 供应商标识
Element.ProductID = Convert.ToUInt16(match.Value.Substring(13, 4), 16); // 产品编号
Element.ClassGuid = new Guid(Entity["ClassGuid"] as String); // 设备安装类GUID
PnPEntities.Add(Element);
}
}
}
if (PnPEntities.Count == 0) return null; else return PnPEntities.ToArray();
}
///
/// 根据VID和PID定位即插即用设备实体
///
/// 供应商标识,MinValue忽视
/// 产品编号,MinValue忽视
/// 设备列表
public static PnPEntityInfo[] WhoPnPEntity(UInt16 VendorID, UInt16 ProductID)
{
return WhoPnPEntity(VendorID, ProductID, Guid.Empty);
}
///
/// 根据设备安装类GUID定位即插即用设备实体
///
/// 设备安装类Guid,Empty忽视
/// 设备列表
public static PnPEntityInfo[] WhoPnPEntity(Guid ClassGuid)
{
return WhoPnPEntity(UInt16.MinValue, UInt16.MinValue, ClassGuid);
}
///
/// 根据设备ID定位设备
///
/// 设备ID,可以是不完整信息
/// 设备列表
///
/// 注意:对于下划线,需要写成“[_]”,否则视为任意字符
///
public static PnPEntityInfo[] WhoPnPEntity(String PNPDeviceID)
{
List PnPEntities = new List();
// 枚举即插即用设备实体
String QueryString;
if (String.IsNullOrEmpty(PNPDeviceID))
{
QueryString = "SELECT * FROM Win32_PnPEntity WHERE PNPDeviceID LIKE '%VID[_]____&PID[_]____%'";
}
else
{ // LIKE子句中有反斜杠字符将会引发WQL查询异常
QueryString = "SELECT * FROM Win32_PnPEntity WHERE PNPDeviceID LIKE '%" + PNPDeviceID.Replace('\\', '_') + "%'";
}
ManagementObjectCollection PnPEntityCollection = new ManagementObjectSearcher(QueryString).Get();
if (PnPEntityCollection != null)
{
foreach (ManagementObject Entity in PnPEntityCollection)
{
String thePNPDeviceID = Entity["PNPDeviceID"] as String;
Match match = Regex.Match(thePNPDeviceID, "VID_[0-9|A-F]{4}&PID_[0-9|A-F]{4}");
if (match.Success)
{
PnPEntityInfo Element;
Element.PNPDeviceID = thePNPDeviceID; // 设备ID
Element.Name = Entity["Name"] as String; // 设备名称
Element.Description = Entity["Description"] as String; // 设备描述
Element.Service = Entity["Service"] as String; // 服务
Element.Status = Entity["Status"] as String; // 设备状态
Element.VendorID = Convert.ToUInt16(match.Value.Substring(4, 4), 16); // 供应商标识
Element.ProductID = Convert.ToUInt16(match.Value.Substring(13, 4), 16); // 产品编号
Element.ClassGuid = new Guid(Entity["ClassGuid"] as String); // 设备安装类GUID
PnPEntities.Add(Element);
}
}
}
if (PnPEntities.Count == 0) return null; else return PnPEntities.ToArray();
}
///
/// 根据服务定位设备
///
/// 要查询的服务集合,null忽视
/// 设备列表
///
/// 跟服务相关的类:
/// Win32_SystemDriverPNPEntity
/// Win32_SystemDriver
///
public static PnPEntityInfo[] WhoPnPEntity(String[] ServiceCollection)
{
if (ServiceCollection == null || ServiceCollection.Length == 0)
return WhoPnPEntity(UInt16.MinValue, UInt16.MinValue, Guid.Empty);
List PnPEntities = new List();
// 枚举即插即用设备实体
String QueryString = "SELECT * FROM Win32_PnPEntity WHERE PNPDeviceID LIKE '%VID[_]____&PID[_]____%'";
ManagementObjectCollection PnPEntityCollection = new ManagementObjectSearcher(QueryString).Get();
if (PnPEntityCollection != null)
{
foreach (ManagementObject Entity in PnPEntityCollection)
{
String PNPDeviceID = Entity["PNPDeviceID"] as String;
Match match = Regex.Match(PNPDeviceID, "VID_[0-9|A-F]{4}&PID_[0-9|A-F]{4}");
if (match.Success)
{
String theService = Entity["Service"] as String; // 服务
if (String.IsNullOrEmpty(theService)) continue;
foreach (String Service in ServiceCollection)
{ // 注意:忽视大小写
if (String.Compare(theService, Service, true) != 0) continue;
PnPEntityInfo Element;
Element.PNPDeviceID = PNPDeviceID; // 设备ID
Element.Name = Entity["Name"] as String; // 设备名称
Element.Description = Entity["Description"] as String; // 设备描述
Element.Service = theService; // 服务
Element.Status = Entity["Status"] as String; // 设备状态
Element.VendorID = Convert.ToUInt16(match.Value.Substring(4, 4), 16); // 供应商标识
Element.ProductID = Convert.ToUInt16(match.Value.Substring(13, 4), 16); // 产品编号
Element.ClassGuid = new Guid(Entity["ClassGuid"] as String); // 设备安装类GUID
PnPEntities.Add(Element);
break;
}
}
}
}
if (PnPEntities.Count == 0) return null; else return PnPEntities.ToArray();
}
#endregion
}
}
C# 枚举Bus Reported Device Desc
有了C++的例证,只需要通过P/Invoke改成C#的方法即可。
此方法主要是为了枚举BusReportedDeviceDesc.
public class UsbEnumHelper
{
static DEVPROPKEY DEVPKEY_Device_BusReportedDeviceDesc;
#region Dlls
[DllImport("setupapi.dll", SetLastError = true)]
private static extern IntPtr SetupDiGetClassDevs(
ref Guid gClass, UInt32 iEnumerator, UInt32 hParent, DiGetClassFlags nFlags);
[DllImport("setupapi.dll", SetLastError = true)]
private static extern bool SetupDiEnumDeviceInfo(
IntPtr DeviceInfoSet, UInt32 MemberIndex, ref SP_DEVINFO_DATA DeviceInterfaceData);
[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool SetupDiGetDeviceRegistryProperty(
IntPtr DeviceInfoSet,
ref SP_DEVINFO_DATA DeviceInfoData,
SPDRP Property,
out UInt32 PropertyRegDataType,
byte[] PropertyBuffer,
uint PropertyBufferSize,
out UInt32 RequiredSize);
[DllImport("setupapi.dll", SetLastError = true)]
static extern bool SetupDiClassGuidsFromName(string ClassName,
ref Guid ClassGuidArray1stItem, UInt32 ClassGuidArraySize,
out UInt32 RequiredSize);
[DllImport("setupapi.dll", SetLastError = true)]
static extern bool SetupDiGetDevicePropertyW(
IntPtr deviceInfoSet,
[In] ref SP_DEVINFO_DATA DeviceInfoData,
[In] ref DEVPROPKEY propertyKey,
[Out] out UInt32 propertyType,
byte[] propertyBuffer,
UInt32 propertyBufferSize,
out UInt32 requiredSize,
UInt32 flags);
#endregion
#region Enums
public enum SPDRP : uint
{
///
/// DeviceDesc (R/W)
///
SPDRP_DEVICEDESC = 0x00000000,
///
/// HardwareID (R/W)
///
SPDRP_HARDWAREID = 0x00000001,
///
/// CompatibleIDs (R/W)
///
SPDRP_COMPATIBLEIDS = 0x00000002,
///
/// unused
///
SPDRP_UNUSED0 = 0x00000003,
///
/// Service (R/W)
///
SPDRP_SERVICE = 0x00000004,
///
/// unused
///
SPDRP_UNUSED1 = 0x00000005,
///
/// unused
///
SPDRP_UNUSED2 = 0x00000006,
///
/// Class (R--tied to ClassGUID)
///
SPDRP_CLASS = 0x00000007,
///
/// ClassGUID (R/W)
///
SPDRP_CLASSGUID = 0x00000008,
///
/// Driver (R/W)
///
SPDRP_DRIVER = 0x00000009,
///
/// ConfigFlags (R/W)
///
SPDRP_CONFIGFLAGS = 0x0000000A,
///
/// Mfg (R/W)
///
SPDRP_MFG = 0x0000000B,
///
/// FriendlyName (R/W)
///
SPDRP_FRIENDLYNAME = 0x0000000C,
///
/// LocationInformation (R/W)
///
SPDRP_LOCATION_INFORMATION = 0x0000000D,
///
/// PhysicalDeviceObjectName (R)
///
SPDRP_PHYSICAL_DEVICE_OBJECT_NAME = 0x0000000E,
///
/// Capabilities (R)
///
SPDRP_CAPABILITIES = 0x0000000F,
///
/// UiNumber (R)
///
SPDRP_UI_NUMBER = 0x00000010,
///
/// UpperFilters (R/W)
///
SPDRP_UPPERFILTERS = 0x00000011,
///
/// LowerFilters (R/W)
///
SPDRP_LOWERFILTERS = 0x00000012,
///
/// BusTypeGUID (R)
///
SPDRP_BUSTYPEGUID = 0x00000013,
///
/// LegacyBusType (R)
///
SPDRP_LEGACYBUSTYPE = 0x00000014,
///
/// BusNumber (R)
///
SPDRP_BUSNUMBER = 0x00000015,
///
/// Enumerator Name (R)
///
SPDRP_ENUMERATOR_NAME = 0x00000016,
///
/// Security (R/W, binary form)
///
SPDRP_SECURITY = 0x00000017,
///
/// Security (W, SDS form)
///
SPDRP_SECURITY_SDS = 0x00000018,
///
/// Device Type (R/W)
///
SPDRP_DEVTYPE = 0x00000019,
///
/// Device is exclusive-access (R/W)
///
SPDRP_EXCLUSIVE = 0x0000001A,
///
/// Device Characteristics (R/W)
///
SPDRP_CHARACTERISTICS = 0x0000001B,
///
/// Device Address (R)
///
SPDRP_ADDRESS = 0x0000001C,
///
/// UiNumberDescFormat (R/W)
///
SPDRP_UI_NUMBER_DESC_FORMAT = 0X0000001D,
///
/// Device Power Data (R)
///
SPDRP_DEVICE_POWER_DATA = 0x0000001E,
///
/// Removal Policy (R)
///
SPDRP_REMOVAL_POLICY = 0x0000001F,
///
/// Hardware Removal Policy (R)
///
SPDRP_REMOVAL_POLICY_HW_DEFAULT = 0x00000020,
///
/// Removal Policy Override (RW)
///
SPDRP_REMOVAL_POLICY_OVERRIDE = 0x00000021,
///
/// Device Install State (R)
///
SPDRP_INSTALL_STATE = 0x00000022,
///
/// Device Location Paths (R)
///
SPDRP_LOCATION_PATHS = 0x00000023,
}
[StructLayout(LayoutKind.Sequential)]
struct DEVPROPKEY
{
public Guid fmtid;
public UInt32 pid;
}
public struct DeviceInfo
{
public string hadware_id;
public string bus_description;
public string p_id;
public string v_id;
}
[StructLayout(LayoutKind.Sequential)]
private struct SP_DEVINFO_DATA
{
public UInt32 cbSize;
public Guid ClassGuid;
public UInt32 DevInst;
public UIntPtr Reserved;
};
[Flags]
public enum DiGetClassFlags : uint
{
DIGCF_DEFAULT = 0x00000001, // only valid with DIGCF_DEVICEINTERFACE
DIGCF_PRESENT = 0x00000002,
DIGCF_ALLCLASSES = 0x00000004,
DIGCF_PROFILE = 0x00000008,
DIGCF_DEVICEINTERFACE = 0x00000010,
}
const int BUFFER_SIZE = 1024;
const int utf16terminatorSize_bytes = 2;
#endregion
#region Methods
public static DeviceInfo GetFlickerDeviceInfo()
{
DEVPKEY_Device_BusReportedDeviceDesc = new DEVPROPKEY();
DEVPKEY_Device_BusReportedDeviceDesc.fmtid = new Guid(0x540b947e, 0x8b40, 0x45bc, 0xa8, 0xa2, 0x6a, 0x0b, 0x89, 0x4c, 0xbd, 0xa2);
DEVPKEY_Device_BusReportedDeviceDesc.pid = 4;
Guid[] guids = GetClassGUIDs("Usb");
var hDevInfo = SetupDiGetClassDevs(ref guids[0], 0, 0, DiGetClassFlags.DIGCF_PRESENT);
try
{
UInt32 iMemberIndex = 0;
while (true)
{
SP_DEVINFO_DATA deviceInfoData = new SP_DEVINFO_DATA();
deviceInfoData.cbSize = (uint)Marshal.SizeOf(typeof(SP_DEVINFO_DATA));
bool success = SetupDiEnumDeviceInfo(hDevInfo, iMemberIndex, ref deviceInfoData);
if (!success)
{
// No more devices in the device information set
break;
}
DeviceInfo deviceInfo = new DeviceInfo();
deviceInfo.hadware_id = GetDeviceDescription(hDevInfo, deviceInfoData);
deviceInfo.bus_description = GetDeviceBusDescription(hDevInfo, deviceInfoData);
if (deviceInfo.bus_description.Contains("Flicker"))
{
deviceInfo.v_id = deviceInfo.hadware_id.Substring(8, 4);
deviceInfo.p_id = deviceInfo.hadware_id.Substring(17, 4);
return deviceInfo;
}
iMemberIndex++;
}
}
catch (Exception e)
{
}
return new DeviceInfo();
}
private static string GetDeviceDescription(IntPtr hDeviceInfoSet, SP_DEVINFO_DATA deviceInfoData)
{
byte[] ptrBuf = new byte[BUFFER_SIZE];
uint propRegDataType;
uint RequiredSize;
bool success = SetupDiGetDeviceRegistryProperty(hDeviceInfoSet, ref deviceInfoData, SPDRP.SPDRP_HARDWAREID,
out propRegDataType, ptrBuf, BUFFER_SIZE, out RequiredSize);
if (!success)
{
throw new Exception("Can not read registry value PortName for device " + deviceInfoData.ClassGuid);
}
return Encoding.Unicode.GetString(ptrBuf, 0, (int)RequiredSize - utf16terminatorSize_bytes);
}
private static Guid[] GetClassGUIDs(string className)
{
UInt32 requiredSize = 0;
Guid[] guidArray = new Guid[1];
bool status = SetupDiClassGuidsFromName(className, ref guidArray[0], 1, out requiredSize);
if (true == status)
{
if (1 < requiredSize)
{
guidArray = new Guid[requiredSize];
SetupDiClassGuidsFromName(className, ref guidArray[0], requiredSize, out requiredSize);
}
}
else
throw new System.ComponentModel.Win32Exception();
return guidArray;
}
private static string GetDeviceBusDescription(IntPtr hDeviceInfoSet, SP_DEVINFO_DATA deviceInfoData)
{
byte[] ptrBuf = new byte[BUFFER_SIZE];
uint propRegDataType;
uint RequiredSize;
bool success = SetupDiGetDevicePropertyW(hDeviceInfoSet, ref deviceInfoData, ref DEVPKEY_Device_BusReportedDeviceDesc,
out propRegDataType, ptrBuf, BUFFER_SIZE, out RequiredSize, 0);
if (!success)
{
//throw new Exception("Can not read Bus provided device description device " + deviceInfoData.ClassGuid);
return "Err";
}
return System.Text.UnicodeEncoding.Unicode.GetString(ptrBuf, 0, (int)RequiredSize - utf16terminatorSize_bytes);
}
#endregion
}