C# 读取设备 属性

C# reading a device property

我一直在尝试使用 WMI 从设备属性中提取一些信息。 但它没有在任何地方列出,或者至少我找不到它。

root\CIMV2, SELECT * FROM Win32_VideoController 是我正在看的地方。

谁能指出我正确的方向?

Propertie searching for

无法通过 WMI 获得该信息。为此,您必须使用 Setup API。由于这是 C/C++ API,您必须自己在 C# 中导入和定义一些类型。

P/Invoke定义

static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);

static readonly Guid DisplayAdapter = new Guid("{5B45201D-F2F2-4F3B-85BB-30FF1F953599}");

[Flags]
enum DiGetClassFlags : uint
{
    DIGCF_DEFAULT = 0x00000001, // only valid with DIGCF_DEVICEINTERFACE
    DIGCF_PRESENT = 0x00000002,
    DIGCF_ALLCLASSES = 0x00000004,
    DIGCF_PROFILE = 0x00000008,
    DIGCF_DEVICEINTERFACE = 0x00000010,
}

[Flags]
enum DEVPROPTYPE : ulong
{
    DEVPROP_TYPEMOD_ARRAY = 0x00001000,
    DEVPROP_TYPEMOD_LIST = 0x00002000,

    DEVPROP_TYPE_EMPTY = 0x00000000,  // nothing, no property data
    DEVPROP_TYPE_NULL = 0x00000001,  // null property data
    DEVPROP_TYPE_SBYTE = 0x00000002,  // 8-bit signed int (SBYTE)
    DEVPROP_TYPE_BYTE = 0x00000003,  // 8-bit unsigned int (BYTE)
    DEVPROP_TYPE_INT16 = 0x00000004,  // 16-bit signed int (SHORT)
    DEVPROP_TYPE_UINT16 = 0x00000005,  // 16-bit unsigned int (USHORT)
    DEVPROP_TYPE_INT32 = 0x00000006,  // 32-bit signed int (LONG)
    DEVPROP_TYPE_UINT32 = 0x00000007,  // 32-bit unsigned int (ULONG)
    DEVPROP_TYPE_INT64 = 0x00000008,  // 64-bit signed int (LONG64)
    DEVPROP_TYPE_UINT64 = 0x00000009,  // 64-bit unsigned int (ULONG64)
    DEVPROP_TYPE_FLOAT = 0x0000000A,  // 32-bit floating-point (FLOAT)
    DEVPROP_TYPE_DOUBLE = 0x0000000B,  // 64-bit floating-point (DOUBLE)
    DEVPROP_TYPE_DECIMAL = 0x0000000C,  // 128-bit data (DECIMAL)
    DEVPROP_TYPE_GUID = 0x0000000D,  // 128-bit unique identifier (GUID)
    DEVPROP_TYPE_CURRENCY = 0x0000000E,  // 64 bit signed int currency value (CURRENCY)
    DEVPROP_TYPE_DATE = 0x0000000F,  // date (DATE)
    DEVPROP_TYPE_FILETIME = 0x00000010,  // filetime (FILETIME)
    DEVPROP_TYPE_BOOLEAN = 0x00000011,  // 8-bit boolean (DEVPROP_BOOLEAN)
    DEVPROP_TYPE_STRING = 0x00000012,  // null-terminated string
    DEVPROP_TYPE_STRING_LIST = (DEVPROP_TYPE_STRING | DEVPROP_TYPEMOD_LIST), // multi-sz string list
    DEVPROP_TYPE_SECURITY_DESCRIPTOR = 0x00000013,  // self-relative binary SECURITY_DESCRIPTOR
    DEVPROP_TYPE_SECURITY_DESCRIPTOR_STRING = 0x00000014,  // security descriptor string (SDDL format)
    DEVPROP_TYPE_DEVPROPKEY = 0x00000015,  // device property key (DEVPROPKEY)
    DEVPROP_TYPE_DEVPROPTYPE = 0x00000016,  // device property type (DEVPROPTYPE)
    DEVPROP_TYPE_BINARY = (DEVPROP_TYPE_BYTE | DEVPROP_TYPEMOD_ARRAY),  // custom binary data
    DEVPROP_TYPE_ERROR = 0x00000017,  // 32-bit Win32 system error code
    DEVPROP_TYPE_NTSTATUS = 0x00000018, // 32-bit NTSTATUS code
    DEVPROP_TYPE_STRING_INDIRECT = 0x00000019, // string resource (@[path\]<dllname>,-<strId>)

    MAX_DEVPROP_TYPE = 0x00000019,
    MAX_DEVPROP_TYPEMOD = 0x00002000,

    DEVPROP_MASK_TYPE = 0x00000FFF,
    DEVPROP_MASK_TYPEMOD = 0x0000F000
}

[StructLayout(LayoutKind.Sequential)]
struct SP_DEVINFO_DATA
{
    public uint cbSize;
    public Guid classGuid;
    public uint devInst;
    public IntPtr reserved;
}

[StructLayout(LayoutKind.Sequential)]
struct DEVPROPKEY
{
    public Guid fmtid;
    public UInt32 pid;
}

[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr SetupDiGetClassDevs(ref Guid classGuid, [MarshalAs(UnmanagedType.LPTStr)] string enumerator, IntPtr hwndParent, DiGetClassFlags flags);

[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool SetupDiEnumDeviceInfo([In] IntPtr hDevInfo, [In] uint memberIndex, [In, Out] ref SP_DEVINFO_DATA deviceInfoData);

[DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern bool SetupDiGetDeviceProperty([In] IntPtr hDevInfo, [In] ref SP_DEVINFO_DATA deviceInfoData, [In] ref DEVPROPKEY propertyKey, [In, Out] ref DEVPROPTYPE propertyType, [In, Out] byte[] propertyBuffer, [In] uint propertyBufferSize, [In, Out] ref uint requiredSize, [In] uint flags = 0);

用法

var dpk = new DEVPROPKEY();
dpk.fmtid = new Guid("60b193cb-5276-4d0f-96fc-f173abad3ec6");
dpk.pid = 2;

var displayDevClass = new Guid(DisplayAdapter.ToString());
var hDevInfo = SetupDiGetClassDevs(ref displayDevClass, null, IntPtr.Zero, DiGetClassFlags.DIGCF_PRESENT | DiGetClassFlags.DIGCF_DEVICEINTERFACE);

if (hDevInfo != INVALID_HANDLE_VALUE)
{
    uint i = 0;
    while (true)
    {
        var did = new SP_DEVINFO_DATA();
        did.cbSize = (uint)Marshal.SizeOf(did);
        if (!SetupDiEnumDeviceInfo(hDevInfo, i, ref did)) break;

        uint required = 0;
        DEVPROPTYPE dpt = 0;
        var temp = new byte[0];
        SetupDiGetDeviceProperty(hDevInfo, ref did, ref dpk, ref dpt, temp, 0, ref required);
        if (required > 0)
        {
            var data = new byte[required];
            if (SetupDiGetDeviceProperty(hDevInfo, ref did, ref dpk, ref dpt, data, required, ref required))
            {
                Console.WriteLine(BitConverter.ToString(data));
            }
        }
    }
}