背景及问题:在与硬件打交道时,经常需要知道当前设备连接的硬件信息,以便连接正确的硬件,比如串口通讯查询连接的硬件及端口,一般手工的方式就是去设备管理器查看相应的信息,应用程序如何读取这一部分信息呢,Windows下的SetupAPI系列就可以解决这个问题示例程序

#include#include#include#include#pragma comment(lib, "setupapi.lib")int main(){//set chinese characterstd::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的使用

  1. SetupDiGetClassDevs –>获取设备信息的集合
  2. SetupDiEnumDeviceInfo –>针对具体的设备解析信息
  3. SetupDiGetDeviceRegistryProperty –>提取具体设备的感兴趣信息

其中SetupDiGetClassDevs定义如下

WINSETUPAPI HDEVINFO SetupDiGetClassDevsW(  [in, optional] const GUID *ClassGuid,  [in, optional] PCWSTR     Enumerator,  [in, optional] HWND       hwndParent,  [in]           DWORD      Flags);
ParameterDescription
[in, optional]const GUID *ClassGuid指向设备设置类或设备接口GUID的指针。可为NULL(可选)
[in, optional] PCWSTR Enumerator指定设备种类。可为NULL(可选)
[in, optional] HWND hwndParent显示设备信息UI界面窗口句柄。可为NULL(可选)
[in, optional] DWORD Flags过滤设备信息标志位
返回值HDEVINFO返回设备信息的集合

程序中前三个均设置为NULL,第四个标志位设为DIGCF_PRESENT|DIGCF_ALLCLASSES,表示当前系统已安装的所有设备,还有一些标志参见

MSDN页面-SetupDiGetClassDevsW

拿到设备信息集合之后,使用SetupDiEnumDeviceInfo进行单个设备信息的解析

WINSETUPAPI BOOL SetupDiEnumDeviceInfo(  [in]  HDEVINFO         DeviceInfoSet,  [in]  DWORD            MemberIndex,  [out] PSP_DEVINFO_DATA DeviceInfoData);
ParameterDescription
[in] HDEVINFO DeviceInfoSet设备信息集合句柄
[in] DWORD MemberIndex集合中第几个设备
[out] PSP_DEVINFO_DATA DeviceInfoData具体的设备信息数据

拿到单个设备的信息之后(仍包含很多信息),使用SetupDiGetDeviceRegistryProperty对感兴趣的信息解析

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);
ParameterDescription
[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(可选)

程序中设备属性设置为SPDRP_DEVICEDESC,查询的是设备名的描述,还有很多属性参见

MSDN页面-SetupDiGetDeviceRegistryPropertyW

需要注意的是

  • windows API 通常分单双字节版本,单字节版本一般调用A结尾的API,对应的VS项目属性中字符集为Multi-Byte,双字节版本一般调用以w结尾的API,对应VS项目属性中字符集为Unicode。本例项目属性为Unicode,对应双字节字符串版本,所以输出信息以wcout输出,缓冲区指针转换为wchar_t*
  • TCHAR为自动根据项目中字符集属性转为char(Multi-Byte)或wchar(Unicode)

作者:robot2017
出处:https://www.cnblogs.com/stephen2023/p/17898051.html
版权:本文版权归作者和博客园共有
转载:欢迎转载,但未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任