C# Usb设备信息枚举总结(可枚举Bus Reported Device Desc)

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
    }

你可能感兴趣的:(C# Usb设备信息枚举总结(可枚举Bus Reported Device Desc))