Windows下获取设备管理器列表信息-setupAPI
背景及问题:
在与硬件打交道时,经常需要知道当前设备连接的硬件信息,以便连接正确的硬件,比如串口通讯查询连接的硬件及端口,一般手工的方式就是去设备管理器查看相应的信息,应用程序如何读取这一部分信息呢,Windows下的SetupAPI系列就可以解决这个问题示例程序
#include<Windows.h>
#include<SetupAPI.h>
#include<iostream>
#include<string>
#pragma comment(lib, "setupapi.lib")
int main()
{
//set chinese character
std::locale::global(std::locale(""));
//The SetupDiGetClassDevs function returns a handle to a device
//information set that contains requested device information
//elements for a local computer.
HDEVINFO hdevinfo = SetupDiGetClassDevs(NULL,
NULL, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES);
if (hdevinfo != INVALID_HANDLE_VALUE)
{
DWORD MemberIndex = 0;
SP_DEVINFO_DATA sp_devinfo_data;
ZeroMemory(&sp_devinfo_data, sizeof(sp_devinfo_data));
sp_devinfo_data.cbSize = sizeof(sp_devinfo_data);
//The SetupDiEnumDeviceInfo function returns a SP_DEVINFO_DATA
//structure that specifies a device information element in a
//device information set.
while (SetupDiEnumDeviceInfo(hdevinfo, MemberIndex, &sp_devinfo_data))
{
TCHAR PropertyBuffer[100];
//The SetupDiGetDeviceRegistryProperty function retrieves
//a specified Plug and Play device property.
if (SetupDiGetDeviceRegistryProperty(hdevinfo,
&sp_devinfo_data,
SPDRP_DEVICEDESC,
NULL,
(PBYTE)&PropertyBuffer,
sizeof(PropertyBuffer),
NULL))
{
std::wcout << MemberIndex << ":" << (wchar_t*)PropertyBuffer << std::endl;
}
MemberIndex++;
}
}
return 0;
}
解释
主要是3个API的使用- SetupDiGetClassDevs -->获取设备信息的集合
- SetupDiEnumDeviceInfo -->针对具体的设备解析信息
- SetupDiGetDeviceRegistryProperty -->提取具体设备的感兴趣信息
其中SetupDiGetClassDevs定义如下
WINSETUPAPI HDEVINFO SetupDiGetClassDevsW(
[in, optional] const GUID *ClassGuid,
[in, optional] PCWSTR Enumerator,
[in, optional] HWND hwndParent,
[in] DWORD Flags
);
Parameter | Description |
---|---|
[in, optional]const GUID *ClassGuid | 指向设备设置类或设备接口GUID的指针。可为NULL(可选) |
[in, optional] PCWSTR Enumerator | 指定设备种类。可为NULL(可选) |
[in, optional] HWND hwndParent | 显示设备信息UI界面窗口句柄。可为NULL(可选) |
[in, optional] DWORD Flags | 过滤设备信息标志位 |
返回值HDEVINFO | 返回设备信息的集合 |
拿到设备信息集合之后,使用SetupDiEnumDeviceInfo进行单个设备信息的解析
WINSETUPAPI BOOL SetupDiEnumDeviceInfo(
[in] HDEVINFO DeviceInfoSet,
[in] DWORD MemberIndex,
[out] PSP_DEVINFO_DATA DeviceInfoData
);
Parameter | Description |
---|---|
[in] HDEVINFO DeviceInfoSet | 设备信息集合句柄 |
[in] DWORD MemberIndex | 集合中第几个设备 |
[out] PSP_DEVINFO_DATA DeviceInfoData | 具体的设备信息数据 |
WINSETUPAPI BOOL SetupDiGetDeviceRegistryPropertyW(
[in] HDEVINFO DeviceInfoSet,
[in] PSP_DEVINFO_DATA DeviceInfoData,
[in] DWORD Property,
[out, optional] PDWORD PropertyRegDataType,
[out, optional] PBYTE PropertyBuffer,
[in] DWORD PropertyBufferSize,
[out, optional] PDWORD RequiredSize
);
Parameter | Description |
---|---|
[in] HDEVINFO | 设备信息集合句柄 |
[in] PSP_DEVINFO_DATA DeviceInfoData | 具体的设备信息数据 |
[in] DWORD Property | 设备属性 |
[out, optional] PDWORD PropertyRegDataType | 指向接收所检索属性的数据类型变量的指针。可为NULL(可选) |
[out, optional] PBYTE PropertyBuffer | 指向接收正在检索的属性的缓冲区的指针 |
[in] DWORD PropertyBufferSize | 缓冲区大小 |
[out, optional] PDWORD RequiredSize | 缓冲区的所需大小。可为NULL(可选) |
MSDN页面-SetupDiGetDeviceRegistryPropertyW
需要注意的是
- windows API 通常分单双字节版本,单字节版本一般调用A结尾的API,对应的VS项目属性中字符集为Multi-Byte,双字节版本一般调用以w结尾的API,对应VS项目属性中字符集为Unicode。本例项目属性为Unicode,对应双字节字符串版本,所以输出信息以wcout输出,缓冲区指针转换为wchar_t*
- TCHAR为自动根据项目中字符集属性转为char(Multi-Byte)或wchar(Unicode)