QT案例 使用WMI获取win_32类的属性值,包括Win32提供程序类中的属性
最近涉及到读取WINDOWS 系统电脑设备的各种信息,在一些特殊的PE或者简化系统中是没有WMI查询工具的,所以就自己写了个查询大部分WMI属性值的工具,免去了查网站的功夫。涉及到的方法内容就汇总做个总结。
PS:因为工作中软件基本都是我一个人开发和维护,所以一般就写一堆一个方法,最近看了很多 GitHub上的代码顿时有种写了一堆屎的感觉,啧啧,向诸位大佬学习借鉴
Win32提供程序查询主要代码
- 初始化COM库
- 获取IWbemServices实例
- WQL查询
- 获取属性名称、类型的另一种写法
- CIMTYPE 数据类型转换
- gumbo-parse解析HTML
- 小工具可执行程序看文章附件资源
- 源码下载
初始化COM库
void _print_hresult(const char *file, int line, const char *msg, HRESULT hr);
#define PRINT_HRESULT(hr, msg) _print_hresult(__FILE__, __LINE__, msg, hr)
#define IFFAILED_PRINTERROR(hr, msg) { HRESULT __hr__ = (hr); if ((__hr__ != RPC_E_TOO_LATE) &&FAILED(__hr__)) { PRINT_HRESULT(__hr__, msg); } }static class BLL_CUSTOM_LIBRARY_EXPORT COMThreading {
public:COMThreading() {// Regardless of return value, you must balance each call to// CoInitialize[Ex] with a call to CoUninitialize.HRESULT hres = CoInitializeEx(0, COINIT_APARTMENTTHREADED);IFFAILED_PRINTERROR(hres, "Error on CoInitializeEx");hres =CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_CONNECT,RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0, NULL);IFFAILED_PRINTERROR(hres, "Error on CoInitializeSecurity");}~COMThreading() {CoUninitialize();}
};
这种初始化COM库的写法真的就很经典,完全不用担心调用后没释放的问题,第一次看到的时候真的觉得大佬真是牛逼。
获取IWbemServices实例
#define PRINT_HRESULT(hr, msg) WMIOBJ_PRINT_ERROR(QString("%1 : %2").arg(msg).arg(GetError(hr)))
#define IFFAILED_PRINTERROR(hr, msg) { HRESULT __hr__ = (hr); if ((__hr__ != RPC_E_TOO_LATE) &&FAILED(__hr__)) { PRINT_HRESULT(__hr__, msg); } }HRESULT GetWMIProxy(const CString &objectPath, CComPtr<IWbemServices> &pSvc)
{WMIOBJ_PRINT_INFO("Execution GetWMIProxy...");HRESULT hres;CComPtr<IWbemLocator> pLoc;hres = CoInitializeSecurity(NULL,-1, // COM authenticationNULL, // Authentication servicesNULL, // ReservedRPC_C_AUTHN_LEVEL_DEFAULT, // Default authenticationRPC_C_IMP_LEVEL_IMPERSONATE, // Default ImpersonationNULL, // Authentication infoEOAC_NONE, // Additional capabilitiesNULL // Reserved);IFFAILED_PRINTERROR(hres, "Error on CoInitializeSecurity.");// Obtain the initial locator to WMIhres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)&pLoc);IFFAILED_RETURN_RES(hres, "Error on CoCreateInstance.");hres = pLoc->ConnectServer(_bstr_t(objectPath), // Object path of WMI namespaceNULL, // User name. NULL = current userNULL, // User password. NULL = current0, // Locale. NULL indicates currentNULL, // Security flags.0, // Authority (for example, Kerberos)0, // Context object&pSvc // pointer to IWbemServices proxy);IFFAILED_RETURN_RES(hres, "Error on pLoc->ConnectServer.");// Set security levels on the proxyhres = CoSetProxyBlanket(pSvc, // Indicates the proxy to setRPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxxRPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxxNULL, // Server principal nameRPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxxRPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxxNULL, // client identityEOAC_NONE // proxy capabilities);IFFAILED_RETURN_RES(hres, "Error on CoSetProxyBlanket.");return hres;
}
硬件方面的命名空间大多是 L"ROOT\CIMV2",宏定义可以这么用我是真的没想到,我以前还是用的简单了,
WQL查询
通过传人WQL查询对应类的所有属性,只做示例,对应参数类型是封装好的,获取返回参数的所有属性,也是有很多种方法。
void Lib_WmiObject::SQL_WQL(QString WQL)
{QueryTitle title;QueryData Data;WMIOBJ_PRINT_INFO("Execution Select WQL...<b>START</b>");COMThreading();HRESULT hres;CComPtr<IWbemServices> pSvc;IFFAILED_RETURN(GetWMIProxy(WMI_NAMESPACE, pSvc), " Lib_WmiQuery : Couldn't get WMI proxy");WMIOBJ_PRINT_INFO("WQL : "+WQL);CComPtr<IEnumWbemClassObject> pEnumerator;hres = pSvc->ExecQuery(bstr_t(L"WQL"),bstr_t(WQL.toStdWString().c_str()),WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,NULL,&pEnumerator);IFFAILED_RETURN(hres, "WQL ["+WQL+"] Execution failure.");if(!pEnumerator)WMIOBJ_PRINT_ERROR("WQL 执行失败:"+QString(GetError()));while (pEnumerator){CComPtr<IWbemClassObject> pclsObj;ULONG uReturn = 0;HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);if(0 == uReturn || pclsObj == NULL){if(hr!=ERROR_INVALID_FUNCTION)WMIOBJ_PRINT_ERROR("WQL 执行失败:"+QString(GetError(hr)));break;}if(title.count()==0){SAFEARRAY* pNames;hres=pclsObj->GetNames(L"",WBEM_FLAG_ALWAYS,NULL,&pNames);if (FAILED(hres)){WMIOBJ_PRINT_ERROR("获取属性名称列表失败!");break;}qDebug()<<"lLbound : "<<pNames->cDims;qDebug()<<"cbElements : "<<pNames->cbElements;BSTR HUGEP *pbstr;// Get a pointer to the elements of the array.hr = SafeArrayAccessData(pNames, (void HUGEP**)&pbstr);if (FAILED(hr))continue;for (int i = 0; i < pNames->rgsabound->cElements; i++){BSTR bstrTemp = pbstr[i];title.append(QString::fromWCharArray(bstrTemp));}SafeArrayDestroy(pNames);}QStringList _Data;foreach (QString name , title) {VARIANT vtProp;CIMTYPE pType= CIM_EMPTY;VariantInit(&vtProp);hr = pclsObj->Get(name.toStdWString().c_str(), 0, &vtProp, &pType, 0);if(FAILED(hr)){_Data.append("[ERROR]");}else_Data.append(check_vatiant_type(vtProp,pType));VariantClear(&vtProp);}Data.append(_Data);}UnCOMThreading();WMIOBJ_PRINT_INFO("Execution Select WQL...<b>END</b>");emit Out_Data(title,Data);
}
获取属性名称、类型的另一种写法
#define IFFAILED_RETURN_RES2(hr, msg) { HRESULT __hr__ = (hr); if (FAILED(__hr__)) { PRINT_HRESULT(__hr__, msg); return __hr__; } }
HRESULT EnumerateProperties(IWbemClassObject * pObject)
{BSTR name;VARIANT val;CIMTYPE type;LONG flavor;IFFAILED_RETURN_RES2(pObject->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY), "BeginEnumeration");qDebug("Properties:");while (pObject->Next(0, &name, &val, &type, &flavor) != WBEM_S_NO_MORE_DATA) {qDebug("%-20ls type=0x%04x val.vt=0x%04x val:%s", name, type, val.vt,check_vatiant_type(val,type).toStdString().c_str());SysFreeString(name);VariantClear(&val);}return S_OK;
}
CIMTYPE 数据类型转换
之前在GitHub上看到过一个VARIANT数据类型转换的,结果忘了保存下来,自己又不想写,GitHub又打不开,所以只有用CIMTYPE 类型转换成QString了
QString Lib_WmiObject::check_vatiant_type(VARIANT Value,CIMTYPE _enum_type)
{if(Value.vt==VT_NULL)return "[NULL]";switch ( _enum_type ){case CIM_ILLEGAL ://值: 0xfff非法值。return QString::fromWCharArray(Value.bstrVal);case CIM_EMPTY : //值: 0 空 (null) 值。return "[NULL]";case CIM_SINT8 : //值: 16//8 位有符号整数。return QString::number(Value.iVal);case CIM_SINT16 : //值: 2//16 位带符号整数。return QString::number(Value.iVal);case CIM_SINT32 : //值: 3//32 位带符号整数。return QString::number(Value.intVal);case CIM_SINT64 : //值: 20//64 位带符号整数。return QString::number(Value.llVal,10);case CIM_UINT8 : //值: 17//8 位无符号整数。return QString::number(Value.uiVal);case CIM_UINT16 : //值: 18//16 位无符号整数。return QString::number(Value.uintVal);case CIM_UINT32 : //值: 19//32 位无符号整数。return QString::number(Value.uintVal);case CIM_UINT64 : //值: 21//64 位无符号整数。return QString::number(Value.ullVal,10);case CIM_REAL32 : //值: 4//32 位实数。return QString::number(Value.intVal);case CIM_REAL64 : //值: 5//64 位实数。return QString::number(Value.ullVal,10);case CIM_BOOLEAN : //值: 11//一个布尔值。return Value.boolVal?"TRUE":"FALSE";case CIM_STRING : // 值: 8// 字符串值。return QString::fromWCharArray(Value.bstrVal);case CIM_DATETIME : //值: 101//一个日期时间值。case CIM_REFERENCE : //值: 102//另一个对象的引用 (__Path) 。case CIM_CHAR16 : //值: 103//16 位字符值。case CIM_OBJECT : //值: 13//Object 值 。case CIM_FLAG_ARRAY : // 值: 0x2000//数组值。return QString::fromWCharArray(Value.bstrVal);default:return QString::fromWCharArray(Value.bstrVal);}
}
gumbo-parse解析HTML
gumbo-parse用来解析html还行。不确定是不是我方法没写对,我之前尝试过用gumbo-parse解析XML,获取不到节点,最后还是用的QT自带的XML解析工具。
* https://blog.csdn.net/chijingjing/article/details/104255763#pragma once
#include "stdafx.h"#include "enumtest.cpp"#include "gumbo-parser/Selector.h"#include "gumbo-parser/Document.h"
#include "gumbo-parser/Selection.h"
#include "gumbo-parser/Node.h"void test_parser() {std::string page("<h1><a>wrong link</a><a class=\"special\"\\>some link</a></h1>");CDocument doc;doc.parse(page.c_str());CSelection c = doc.find("h1 a.special");CNode node = c.nodeAt(0);printf("Node: %s\n", node.text().c_str());std::string content = page.substr(node.startPos(), node.endPos() - node.startPos());printf("Node: %s\n", content.c_str());}void test_html() {std::string page = "<html><div><span>1\n</span>2\n</div></html>";CDocument doc;doc.parse(page.c_str());CNode pNode = doc.find("div").nodeAt(0);std::string content = page.substr(pNode.startPos(), pNode.endPos() - pNode.startPos());printf("Node: #%s#\n", content.c_str());
}void test_escape() {std::string page = "<html><div><span id=\"that's\">1\n</span>2\n</div></html>";CDocument doc;doc.parse(page.c_str());CNode pNode = doc.find("span[id=\"that's\"]").nodeAt(0);std::string content = page.substr(pNode.startPos(), pNode.endPos() - pNode.startPos());printf("Node: #%s#\n", content.c_str());
}int main() {test_parser();test_html();test_escape();
}
————————————————
版权声明:本文为CSDN博主「cejutue」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/chijingjing/article/details/104255763
小工具可执行程序看文章附件资源
源码下载
Qt开发项目案例-以及部分示例的源码下载链接
相关文章:

QT案例 使用WMI获取win_32类的属性值,包括Win32提供程序类中的属性
最近涉及到读取WINDOWS 系统电脑设备的各种信息,在一些特殊的PE或者简化系统中是没有WMI查询工具的,所以就自己写了个查询大部分WMI属性值的工具,免去了查网站的功夫。涉及到的方法内容就汇总做个总结。 PS:因为工作中软件基本都是我一个人开…...
TCP/UDP 的特点、区别及优缺点
1.TCP协议 传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。TCP协议通过建立连接、数据确认(编段号和确认号)和数据重传等机制,保证了数据的可靠性…...

使用 Python 使用贝叶斯神经网络从理论到实践
一、说明 在本文中,我们了解了如何构建一个机器学习模型,该模型结合了神经网络的强大功能,并且仍然保持概率方法进行预测。为了做到这一点,我们可以构建所谓的贝叶斯神经网络。 这个想法不是优化神经网络的损失࿰…...

Linux 中的网站服务管理
目录 1.安装服务 2.启动服务 3.停止服务 4.重启服务 5.开机自启 6.案例 1.安装服务 网址服务程序 yum insatll httpd -y 查看所有服务 systemctl list-unit-files 2.启动服务 systemctl start httpd 查看服务进程,确认是否启动 ps -ef|grep httpd 3.停止…...

阿里云cdn设置相同的域名路径访问不同的oss目录
1.设置回源配置,添加回源URL改写 2.设置跨域,cdn的跨域优先oss 3.回源设置...
提示(Prompt)工程中提示词的开发优化基础概念学习总结
本文对学习过程进行总结,仅对基本思路进行说明,结果在不同的模型上会有差异。 提示与提示工程 提示:指的是向大语言模型输入的特定短语或文本,用于引导模型产生特定的输出,以便模型能够生成符合用户需求的回应。 提示…...

C#基础——语法学习
C#的基本语法 在介绍基本语法之前我们先来大概讲一下创建好的这些文件都是做什么的 .sln文件:将项目和解决方案项结合到一起 .vs文件夹:用来存储当前解决方案中关于用户的设置和自定义项,比如断点,主题等。(一般都将其…...

vue-实现高德地图-省级行政区地块显示+悬浮显示+标签显示
<template><div><div id"container" /><div click"showFn">显示</div><div click"removeFn">移除</div></div> </template><script> import AMapLoader from amap/amap-jsapi-load…...
flutter ‘Gradle Libs‘ was added by build file ‘app/build.gradle‘
相关问题解释文章 How to prefer settings.gradle repositories over build.gradle repositoriesMode 解释 问题描述 此问题是,直接创建的flutter项目,需要配置其他的maven仓库地址,和第三方module,结果始终都是无法成功 错误…...
Java中的链式编程风格与应用案例
引言 链式编程是一种在编程中经常使用的风格,它可以使代码更加简洁、易读和易于维护。在Java中,链式编程可以通过方法链的方式来实现。本文将介绍Java中的链式编程风格,并通过几个应用案例来说明其实际应用。 一、链式编程的概念与特点 链式…...

MTK Android P Sensor架构(一)
需求场景: 本来如果只是给传感器写个驱动并提供能读取温湿度数据的节点,是一件比较轻松的事情,但是最近上层应用的同事要求我们按照安卓标准的流程来,这样他们就能通过注册一个服务直接读取传感器事件数据了。这样做的好处就是第…...

低代码开发与传统软件开发:未来趋势与竞争格局
近年来,低代码开发平台的快速发展引起了各行各业的广泛关注。低代码开发平台简化了软件开发的复杂性,提供了更快速、更灵活的开发方式。于是,许多人开始产生一个疑问:未来低代码开发是否会取代传统软件开发?今天这篇文…...
leetcode 股票问题全序列
1 只允许一次交易,121题,买卖股票的最佳时机 class Solution {/*给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票…...

SpringBoot中日志的使用log4j2
SpringBoot中日志的使用log4j2 1、log4j2介绍 Apache Log4j2 是对 Log4j 的升级,它比其前身 Log4j 1.x 提供了重大改进,并提供了 Logback 中可用的许多改 进,同时修复了 Logback 架构中的一些问题,主要有: 异常处理…...

机械设备企业网站建设的效果如何
机械设备涵盖的类目比较广,其市场需求也是稳增不减,也因此无论大小企业都有增长的机会,当然这也需要靠谱的工具及正确的决策。 对机械设备企业来说,产品品质自然是首位,而向外打造品牌、扩展信息及拓客转化自然也是非…...

设计模式之结构型设计模式(二):工厂模式 抽象工厂模式 建造者模式
工厂模式 Factory 1、什么是工厂模式 工厂模式旨在提供一种统一的接口来创建对象,而将具体的对象实例化的过程延迟到子类或者具体实现中。有助于降低客户端代码与被创建对象之间的耦合度,提高代码的灵活性和可维护性。 定义了一个创建对象的接口&…...

算法模板之单链表图文讲解
🌈个人主页:聆风吟 🔥系列专栏:算法模板、数据结构 🔖少年有梦不应止于心动,更要付诸行动。 文章目录 📋前言一. ⛳️使用数组模拟单链表讲解1.1 🔔为什么我们要使用数组去模拟单链表…...

【强化学习-读书笔记】表格型问题的 Model-Free 方法
参考 Reinforcement Learning, Second Edition An Introduction By Richard S. Sutton and Andrew G. Barto无模型方法 在前面的文章中,我们介绍的是有模型方法(Model-Based)。在强化学习中,"Model"可以理解为算法…...
【手撕算法系列】k-means
k-means k-means算法介绍 k-means算法介绍 K-means算法是一种用于聚类的迭代算法,它将数据集划分为K个簇,其中每个数据点属于与其最近的簇的中心。这个算法的目标是最小化簇内的平方和误差(簇内数据点与簇中心的距离的平方和)。 …...

D33|动态规划!启程!
1.动态规划五部曲: 1)确定dp数组(dp table)以及下标的含义 2)确定递推公式 3)dp数组如何初始化 4)确定遍历顺序 5)举例推导dp数组 2.动态规划应该如何debug 找问题的最好方式就是把…...

大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...

大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...