如何使用C#获取总线报告的设备描述

我试图从Windows设备管理器(Windows 7)获取一个值。

我要搜索的属性名称是Bus Reported Device Description。

我使用以下代码获取设备名称。

请帮我看一下Bus报告的设备描述。

void OtherDevices() { ManagementObjectSearcher deviceList = new ManagementObjectSearcher("Select Name, Status from Win32_PnPEntity"); if (deviceList != null) { foreach (ManagementObject device in deviceList.Get()) { string name = device.GetPropertyValue("Name").ToString(); if (name.Contains("iC5000")) { dgv_HWlist.Rows.Add(name); // break; } } } } 

 string description = (string)device.GetPropertyValue("Description"); 
 namespace flash_tool.common.Utils { using System; using System.Text; using System.Runtime.InteropServices; using System.Collections.Generic; public class Win32DeviceMgmt { [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, } ///  /// Device registry property codes ///  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, } private const UInt32 DICS_FLAG_GLOBAL = 0x00000001; private const UInt32 DIREG_DEV = 0x00000001; private const UInt32 KEY_QUERY_VALUE = 0x0001; ///  /// The SP_DEVINFO_DATA structure defines a device instance that is a member of a device information set. ///  [StructLayout(LayoutKind.Sequential)] private struct SP_DEVINFO_DATA { public UInt32 cbSize; public Guid ClassGuid; public UInt32 DevInst; public UIntPtr Reserved; }; [StructLayout(LayoutKind.Sequential)] struct DEVPROPKEY { public Guid fmtid; public UInt32 pid; } [DllImport("setupapi.dll")] private static extern Int32 SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet); [DllImport("setupapi.dll", SetLastError = true)] private static extern bool SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet, UInt32 MemberIndex, ref SP_DEVINFO_DATA DeviceInterfaceData); [DllImport("setupapi.dll", SetLastError = true)] private static extern IntPtr SetupDiGetClassDevs(ref Guid gClass, UInt32 iEnumerator, UInt32 hParent, DiGetClassFlags nFlags); [DllImport("Setupapi", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr SetupDiOpenDevRegKey(IntPtr hDeviceInfoSet, ref SP_DEVINFO_DATA deviceInfoData, uint scope, uint hwProfile, uint parameterRegistryValueKind, uint samDesired); [DllImport("advapi32.dll", CharSet = CharSet.Unicode, EntryPoint = "RegQueryValueExW", SetLastError = true)] private static extern int RegQueryValueEx(IntPtr hKey, string lpValueName, int lpReserved, out uint lpType, byte[] lpData, ref uint lpcbData); [DllImport("advapi32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] private static extern int RegCloseKey(IntPtr hKey); [DllImport("kernel32.dll")] private static extern Int32 GetLastError(); const int BUFFER_SIZE = 1024; [DllImport("setupapi.dll", SetLastError = true)] static extern bool SetupDiClassGuidsFromName(string ClassName, ref Guid ClassGuidArray1stItem, UInt32 ClassGuidArraySize, out UInt32 RequiredSize); [DllImport("setupapi.dll")] private static extern Int32 SetupDiClassNameFromGuid(ref Guid ClassGuid, StringBuilder className, Int32 ClassNameSize, ref Int32 RequiredSize); ///  /// The SetupDiGetDeviceRegistryProperty function retrieves the specified device property. /// This handle is typically returned by the SetupDiGetClassDevs or SetupDiGetClassDevsEx function. ///  /// Handle to the device information set that contains the interface and its underlying device. /// Pointer to an SP_DEVINFO_DATA structure that defines the device instance. /// Device property to be retrieved. SEE MSDN /// Pointer to a variable that receives the registry data Type. This parameter can be NULL. /// Pointer to a buffer that receives the requested device property. /// Size of the buffer, in bytes. /// Pointer to a variable that receives the required buffer size, in bytes. This parameter can be NULL. /// If the function succeeds, the return value is nonzero. [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 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); const int utf16terminatorSize_bytes = 2; public struct DeviceInfo { public string name; public string description; public string bus_description; } static DEVPROPKEY DEVPKEY_Device_BusReportedDeviceDesc; static Win32DeviceMgmt() { 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; } public static List GetAllCOMPorts() { Guid[] guids = GetClassGUIDs("Ports"); List devices = new List(); for (int index = 0; index < guids.Length; index++) { IntPtr hDeviceInfoSet = SetupDiGetClassDevs(ref guids[index], 0, 0, DiGetClassFlags.DIGCF_PRESENT); if (hDeviceInfoSet == IntPtr.Zero) { throw new Exception("Failed to get device information set for the COM ports"); } 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(hDeviceInfoSet, iMemberIndex, ref deviceInfoData); if (!success) { // No more devices in the device information set break; } DeviceInfo deviceInfo = new DeviceInfo(); deviceInfo.name = GetDeviceName(hDeviceInfoSet, deviceInfoData); deviceInfo.description = GetDeviceDescription(hDeviceInfoSet, deviceInfoData); deviceInfo.bus_description = GetDeviceBusDescription(hDeviceInfoSet, deviceInfoData); devices.Add(deviceInfo); iMemberIndex++; } } finally { SetupDiDestroyDeviceInfoList(hDeviceInfoSet); } } return devices; } private static string GetDeviceName(IntPtr pDevInfoSet, SP_DEVINFO_DATA deviceInfoData) { IntPtr hDeviceRegistryKey = SetupDiOpenDevRegKey(pDevInfoSet, ref deviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE); if (hDeviceRegistryKey == IntPtr.Zero) { throw new Exception("Failed to open a registry key for device-specific configuration information"); } byte[] ptrBuf = new byte[BUFFER_SIZE]; uint length = (uint)ptrBuf.Length; try { uint lpRegKeyType; int result = RegQueryValueEx(hDeviceRegistryKey, "PortName", 0, out lpRegKeyType, ptrBuf, ref length); if (result != 0) { throw new Exception("Can not read registry value PortName for device " + deviceInfoData.ClassGuid); } } finally { RegCloseKey(hDeviceRegistryKey); } return Encoding.Unicode.GetString(ptrBuf, 0, (int)length - utf16terminatorSize_bytes); } 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_DEVICEDESC, 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 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 System.Text.UnicodeEncoding.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; } } } 

离开vromanov的代码。 您需要做的就是获取每个COM端口的总线描述,其中0是First Com,1是第二个,依此类推。

Console.WriteLine(Win32DeviceMgmt.GetAllCOMPorts()[0] .bus_description);