首页查找驱动Windows 日常使用数据挖掘与人工智能搜索引擎与SEO技术备忘录站长随笔

利用Windows API枚举系统已经安装的设备和其安装信息

2019-08-12 Windows API 浏览次数:829
 
想写一个类似“设备管理器”这样的程序



找了一些资料,发现就用三个函数可以了:SetupDiGetClassDevs,SetupDiEnumDeviceInfo,SetupDiGetDeviceRegistryProperty。其实这三个函数跟遍历文件夹非常相似,创建一个句柄,然后利用这个句柄枚举每一项已经安装到系统的设备,然后再读取每一项设备的详细信息值。例如:设备名,驱动程序,所属驱动分类名,系统总线号,等等

1 首先使用SetupDiGetClassDevsA或SetupDiGetClassDevsW函数创建一个设备信息集句柄。

HDEVINFO SetupDiGetClassDevsA(const GUID *ClassGuid,PCWSTR Enumerator,HWND hwndParent,DWORD Flags);

2 然后利用得到的信息设备集句柄,进行枚举 SetupDiEnumDeviceInfo

BOOL SetupDiEnumDeviceInfo(HDEVINFO DeviceInfoSet,DWORD MemberIndex,PSP_DEVINFO_DATA DeviceInfoData);

第一参数就填SetupDiGetClassDevs的返回值句柄;

第二个参数就是要检索的设备信息索引值,从零开始;

第三参数是一个指向SP_DEVINFO_DATA结构的指针,当函数执行成功之后,函数会往该结构填写一些数据

这里重点说下第二个参数,如何知道系统一共有多少个设备呢?其实没人懂啊~~~那怎么办啊,用循环的方法呗,将索引值从零开始累加,直到返回FALSE,就是说明已经没有设备啦。

3 枚举得到设备之后,就可以查询这个设备的各种详细信息啦

BOOL SetupDiGetDeviceRegistryPropertyA(HDEVINFO DeviceInfoSet,PSP_DEVINFO_DATA DeviceInfoData,DWORD Property,PDWORD PropertyRegDataType,PBYTE PropertyBuffer,DWORD PropertyBufferSize,PDWORD RequiredSize);

第一参数就填SetupDiGetClassDevs的返回值句柄;

第二个参数是一个指向SP_DEVINFO_DATA结构的指针,将SetupDiEnumDeviceInfo的第三个参数返回的指针地址填进去

第三个参数是要查询的信息类型,比例说:我们要查询某设备的设备名,驱动程序,系统服务名,系统总线号,等等,常用的值有:SPDRP_CLASS,SPDRP_COMPATIBLEIDS,SPDRP_DEVICEDESC,还有很多值没有列出来,具体可以参考MSDN:https://docs.microsoft.com/zh-cn/windows/win32/api/setupapi/nf-setupapi-setupdigetdeviceregistrypropertya

第四个参数指向接收正在检索的属性的数据类型的变量的指针。这是标准注册表数据类型之一。此参数是可选的,可以为NULL;

第无个参数就是接收返回值的内存区,当函数执行成功的时候,得到的结果将写入这个内存区

第六个参数是第五个参数内存区的长度

第七个参数内存区里保存的结果的数据长度,当函数执行成功的时候,内存区里面的数据长度。

总体的代码大概是这样的:

hDeviceHand=SetupDiGetClassDevsA(0,0,0,DIGCF_PRESENT | DIGCF_ALLCLASSES);

if (hDeviceInfo != INVALID_HANDLE_VALUE){

MemoryBufMaxLen=1024*1024*1;
char* MemoryBuf=new[MemoryBufMaxLen];

int N=0;
while (true){
SP_DEVINFO_DATA DeviceInfoData;
BOOL cs=SetupDiEnumDeviceInfo(hDeviceInfo,N++,&DeviceInfoData);
if (!cs) break;
DWORD RequiredSize=0;
cs:=SetupDiGetDeviceRegistryProperty(hDeviceInfo,&DeviceInfoData,SPDRP_DEVICEDESC,0,MemoryBuf,MemoryBufMaxLen-1,RequiredSize);
if (cs){
// 函数执行成功,信息就存在MemoryBuf里啦,信息长度为RequiredSize
}
} // end while (true)

} // end if (hDeviceInfo != INVALID_HANDLE_VALUE)

我把运行后的信息保存到文件里了,大概就是这样:

留言

有啥想说的就说吧,有啥想问的就问吧
Good good study, day day up!

昵称

Email (填它做啥?国内不兴这玩意,但程序代码里有,我懒得删...)

    ToolBar:

    正在上传图片,请稍等...   

内容  (如果可以的话,最好有相关问题的几张图,特别是出现了错误的时候,当时弹出的错误消息,或者对话框之类的,截图传上来看看吧,这样才好知道具体情况)

查看 HTML 代码(只读模式), 点击返回编辑.

 
最新文章
 
求助
2019 - 2024 mypcrun.com
桂ICP备19002156号-1桂公网安备 45070202000667号
这回把网站设计得那么漂亮,这下子不会被人笑了吧。