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 | 返回设备信息的集合 |
程序中前三个均设置为NULL,第四个标志位设为DIGCF_PRESENT|DIGCF_ALLCLASSES,表示当前系统已安装的所有设备,还有一些标志参见
拿到设备信息集合之后,使用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 | 具体的设备信息数据 |
拿到单个设备的信息之后(仍包含很多信息),使用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
);
| 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(可选) |
程序中设备属性设置为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)
Windows下获取设备管理器列表信息-setupAPI的更多相关文章
- windows下获取IP地址的两种方法
windows下获取IP地址的两种方法: 一种可以获取IPv4和IPv6,但是需要WSAStartup: 一种只能取到IPv4,但是不需要WSAStartup: 如下: 方法一:(可以获取IPv4和I ...
- c和c++在windows下获取时间和计算时间差的方法总结
c/c++在windows下获取时间和计算时间差的几种方法总结 一.标准C和C++都可用 1.获取时间用time_t time( time_t * timer ),计算时间差使用double diff ...
- Windows下获取本机IP地址方法介绍
Windows下获取本机IP地址方法介绍 if((hostinfo = gethostbyname(name)) != NULL) { #if 1 ; printf("IP COUNT: % ...
- Windows下获取高精度时间注意事项
Windows下获取高精度时间注意事项 [转贴 AdamWu] 花了很长时间才得到的经验,与大家分享. 1. RDTSC - 粒度: 纳秒级 不推荐优势: 几乎是能够获得最细粒度的计数器抛弃理由: ...
- C语言实现Windows下获取IP和MAC地址。
C语言实现Windows下获取IP和MAC地址. #include <winsock2.h> #include <stdio.h> #include <stdlib.h& ...
- 【转载】c/c++在windows下获取时间和计算时间差的几种方法总结
一.标准C和C++都可用 1.获取时间用time_t time( time_t * timer ),计算时间差使用double difftime( time_t timer1, time_t time ...
- Windows 下获取硬盘序列号
只获取序列号 以下任意一条命令都可以: wmic diskdrive get serialnumber wmic path win32_physicalmedia get SerialNumber w ...
- c/c++在windows下获取时间和计算时间差的几种方法总结 【转】
http://blog.csdn.net/coder_xia/article/details/6566708 一.标准C和C++都可用 1.获取时间用time_t time( time_t * tim ...
- iOS6.0下获取通讯录用户列表
自iOS6.0后获取通讯录列表需要询问用户,经过用户同意后才可以获取通讯录用户列表.而且ABAddressBookRef的初始化工作也由ABAddressBookCreate函数转变为ABAddres ...
- 让Windows下的Tomcat将控制台信息记录到日志
在开发的过程中经常出现包冲突,却不知道怎么回事,可以在 catalina.bat 里面设置查看class加载日志 set CATALINA_OPTS=-server -Xdebug -Xnoage ...
随机推荐
- centos7使用repo方式安装zabbix4.0
1.安装zabbix的repo源 rpm -ivh https://mirrors.tuna.tsinghua.edu.cn/zabbix/zabbix/4.0/rhel/7/x86_64/zabbi ...
- 工作中常用HTML知识点整理
1.table相关样式 border:设置表格边框大小cellspacing:设置单元格间距cellpadding:设置单元格边界与单元格内容间距border-collapse:设置表格的边框是否被合 ...
- golang中的接口(数据类型)
golang中的接口 Golang 中的接口是一种抽象数据类型,Golang 中接口定义了对象的行为规范,只定义规范 不实现.接口中定义的规范由具体的对象来实现,通俗的讲接口就一个标准,它是对一个对象 ...
- SuspendThread and ResumeThread
记录下,用于复现 #include <windows.h> #include <iostream> LRESULT CALLBACK WndProc(HWND hWnd, UI ...
- 在Hexo中引入本地图片的实现
实现步骤 第一步:修改项目根目录下的_config.yml文件参数post_asset_folder值为true. # 开始使用本地静态资源 post_asset_folder: true 第二步:安 ...
- matplotlib画图中x轴过于密集的解决办法
import matplotlib.ticker as ticker ax.xaxis.set_major_locator(ticker.MultipleLocator(base=10)) # tic ...
- 【Azure K8S】演示修复因AKS密钥过期而导致创建服务不成功的问题(The provided client secret keys for app ****** are expired)
问题描述 在Azure Kubernetes 服务中,创建一个Internal Load Balancer服务,使用以下yaml内容: internallb.yaml apiVersion: v1 k ...
- Java 继承成员变量和继承方法的区别
1 package com.bytezreo.duotai3; 2 3 /** 4 * 5 * @Description 继承成员变量和继承方法的区别 6 * @author Bytezero·zhe ...
- Java 理解“万事万物皆对象”+ 匿名对象的使用
1 /** 2 * 3 * @Description 4 * @author Bytezero·zhenglei! Email:420498246@qq.com 5 * @version 6 * @d ...
- Codeforces Round 924 (Div. 2)B. Equalize(思维+双指针)
目录 题面 链接 题意 题解 代码 题面 链接 B. Equalize 题意 给一个数组\(a\),然后让你给这个数组加上一个排列,求出现最多的次数 题解 赛时没过不应该. 最开始很容易想到要去重,因 ...