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));
}
}
}
}
我一直在尝试使用 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));
}
}
}
}