【Windows】使用 WMI 获取系统版本信息

目录

  • 获取系统版本信息
  • 代码

获取系统版本信息

通过 RtlGetNtVersionNumbers 获取系统版本的方法可能不适用于所有情况,而且将要过时(被废弃)。下面介绍一种通过 WMI 查询并根据版本号进行划分的系统版本解析工具,其他方法还有通过注册表和通过文件属性等等。内部版本号表可以通过官方渠道获取,例如:
Windows 10 更新历史记录;
Windows 11 更新历史记录

代码

sysinfo.h

#pragma once
#include <string>
#include <iostream>
#include <windows.h>
#include <iphlpapi.h>
#include <comdef.h>
#include <Wbemidl.h>
#include <math.h>class SysInfo
{
public:SysInfo();virtual ~SysInfo();bool init_wmi();void uninit_wmi();double get_memory_size();std::string get_os_name();std::string get_host_name();int get_file_flag(std::string file_name);std::string get_area(std::string ip);std::string wstring_to_string(wchar_t* data);protected:
private:bool m_init_wmi = false;IWbemServices* pSvc = NULL;IWbemLocator* pLoc = NULL;HRESULT hres = NULL;
};

SysInfo.cpp

#include "SysInfo.h"#pragma comment(lib, "wbemuuid.lib")
#pragma comment(lib, "iphlpapi.lib")#define  GBYTES  1073741824
#define  MBYTES  1048576
#define  KBYTES  1024
#define  DKBYTES 1024.0SysInfo::SysInfo()
{m_init_wmi = init_wmi();
}SysInfo::~SysInfo()
{uninit_wmi();
}bool SysInfo::init_wmi()
{hres = CoInitializeEx(0, COINIT_MULTITHREADED);if (FAILED(hres)){return false;}hres = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);if (FAILED(hres)){CoUninitialize();return false;}hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc);if (FAILED(hres)){CoUninitialize();return false;}hres = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &pSvc);if (FAILED(hres)){pLoc->Release();CoUninitialize();return false;}hres = CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);if (FAILED(hres)){pSvc->Release();pLoc->Release();CoUninitialize();return false;}return true;
}void SysInfo::uninit_wmi()
{pSvc->Release();pLoc->Release();CoUninitialize();
}//Win32_PhysicalMemorydouble SysInfo::get_memory_size()
{double mem_size = 0;IEnumWbemClassObject* pEnumerator = NULL;hres = pSvc->ExecQuery(bstr_t("WQL"), bstr_t("SELECT * FROM Win32_PhysicalMemory"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);if (FAILED(hres)){pSvc->Release();pLoc->Release();CoUninitialize();return -1;}IWbemClassObject* pclsObj = NULL;ULONG uReturn = 0;while (pEnumerator){HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);if (0 == uReturn){break;}VARIANT vtProp = { 0 };VariantInit(&vtProp);// 标准初始化hr = pclsObj->Get(L"Capacity", 0, &vtProp, 0, 0);std::string data = wstring_to_string(vtProp.bstrVal);mem_size += ::atof(data.c_str());VariantClear(&vtProp);pclsObj->Release();}pEnumerator->Release();double mem_total = mem_size / 1024 / 1024 / 1024;return floor(mem_total * 100) / 100;
}std::string SysInfo::get_os_name()
{std::string res_data;IEnumWbemClassObject* pEnumerator = NULL;hres = pSvc->ExecQuery(bstr_t("WQL"), bstr_t("SELECT * FROM win32_operatingsystem"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);if (FAILED(hres)){pSvc->Release();pLoc->Release();CoUninitialize();return res_data;}IWbemClassObject* pclsObj = NULL;ULONG uReturn = 0;while (pEnumerator){HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);if (0 == uReturn){break;}VARIANT vtProp = { 0 };VariantInit(&vtProp);// 标准初始化hr = pclsObj->Get(L"name", 0, &vtProp, 0, 0);std::string data = wstring_to_string(vtProp.bstrVal);data = data.substr(0, data.find('|'));hr = pclsObj->Get(L"Version", 0, &vtProp, 0, 0);res_data = wstring_to_string(vtProp.bstrVal);std::string restp = res_data;std::string temp = "[";temp += res_data;temp += "] ";temp += data;res_data = temp;// 分割string字符串int pos1 = 0, pos2 = 0;std::string pattern = ".";restp += pattern;std::string s[3];for (int i = 0; i < 3; i++) {pos2 = (int)restp.find(pattern, pos1);s[i] = restp.substr(pos1, static_cast<std::basic_string<char, std::char_traits<char>, std::allocator<char>>::size_type>(pos2) - pos1);pos1 = pos2 + 1;}//for (int i = 0; i < 3; i++) {//std::cout << s[i] << std::endl;//}/*size_t size = s[0].length() + 1;char* MajorVer = (char*)malloc(sizeof(char) * size);if (MajorVer != NULL) strcpy_s(MajorVer, size, s[0].c_str());size = s[1].length() + 1;char* MinorVer = (char*)malloc(sizeof(char) * size);if (MinorVer != NULL) strcpy_s(MinorVer, size, s[1].c_str());size = s[2].length() + 1;char* BuildVer = (char*)malloc(sizeof(char) * size);if (BuildVer != NULL) strcpy_s(BuildVer, size, s[2].c_str());*/int MajorVer = 0, MinorVer = 0, BuildVer = 0, L;L = sscanf_s(s[0].c_str(), "%d", &MajorVer);L = sscanf_s(s[1].c_str(), "%d", &MinorVer);L = sscanf_s(s[2].c_str(), "%d", &BuildVer);printf("大版本号:%d, 小版本号:%d, 内部版本号:%d\n", MajorVer, MinorVer, BuildVer);printf("显式版本: ");if (BuildVer >= 22621) printf("Windows 11 22H2 Or Greater\n");else if (BuildVer >= 22000) printf("Windows 11 21H2\n");else if (BuildVer == 20348) printf("Windows Server 2022\n");else if (BuildVer >= 19045) printf("Windows 10 22H2\n");else if (BuildVer >= 19044) printf("Windows 10 21H2\n");else if (BuildVer >= 19043) printf("Windows 10 21H1\n");else if (BuildVer >= 19042) printf("Windows 10 20H2\n");else if (BuildVer >= 19041) printf("Windows 10 2004\n");else if (BuildVer >= 18363) printf("Windows 10 1909\n");else if (BuildVer >= 18362) printf("Windows 10 1903\n");else if (BuildVer >= 17763) printf("Windows 10 1809\n");else if (BuildVer >= 17134) printf("Windows 10 1803\n");else if (BuildVer >= 16299) printf("Windows 10 1709\n");else if (BuildVer >= 15063) printf("Windows 10 1703\n");else if (BuildVer >= 14393) printf("Windows 10 1607\n");else if (BuildVer >= 10586) printf("Windows 10 1511\n");else if (BuildVer >= 10240) printf("Windows 10 1507\n");// 以下数据属于网络收集,不一定准确,数据已经不可考究else if (BuildVer >= 9200){// 6.2->win 8; 6.3->win 8.1if (MinorVer == 2) printf("Windows 8 Release\n");else if (MinorVer == 3) printf("Windows 8.1 Release\n");}else if (BuildVer >= 7601) printf("Windows 7 Service Pack 1\n");else if (BuildVer >= 7600) printf("Windows 7 Release\n");else if (BuildVer >= 6002) printf("Windows Vista SP2\n");else if (BuildVer >= 6001) printf("Windows Vista SP1\n");else if (BuildVer >= 6000) printf("Windows Vista\n");else if (BuildVer >= 3790) printf("Windows XP Professional x64 Edition\n");else if (BuildVer == 3000) printf("Windows Me");// 版本特殊?else if (BuildVer >= 2600) printf("Windows XP\n");// 存在特殊版本else if (BuildVer == 2222) printf("Windows 98 Second Edition\n");// 版本特殊?else if (BuildVer >= 2195) printf("Windows 2000 Professional\n");else if (BuildVer >= 1998) printf("Windows 98\n");else if (BuildVer >= 1381) printf("Windows NT Workstation 4.0\n");else if (BuildVer >= 1057) printf("Windows NT Workstation 3.51\n");// 版本特殊?else if (BuildVer >= 950) printf("Windows 95\n");else if (BuildVer >= 807) printf("Windows NT Workstation 3.5\n");else if (BuildVer >= 528) printf("Windows NT 3.1\n");else printf("版本特殊或者为远古版本!\n");// 释放//free(MajorVer);//free(MinorVer);//free(BuildVer);VariantClear(&vtProp);pclsObj->Release();}pEnumerator->Release();return res_data;}std::string SysInfo::get_host_name()
{std::string host_name;char buf[MAX_PATH] = { 0 };DWORD length = MAX_PATH;if (::GetComputerNameA(buf, &length)) {host_name = buf;}return host_name;
}int SysInfo::get_file_flag(std::string file_name)
{return 0;
}std::string SysInfo::get_area(std::string ip)
{std::string area;return area;
}std::string SysInfo::wstring_to_string(wchar_t* data)
{std::string res_data;int iSize;// 宽字符串转换iSize = WideCharToMultiByte(CP_ACP, 0, data, -1, NULL, 0, NULL, NULL);char* pCapacity = (char*)malloc(iSize * sizeof(char));if (pCapacity == NULL) return res_data;pCapacity[0] = 0;WideCharToMultiByte(CP_ACP, 0, data, -1, pCapacity, iSize, NULL, NULL);res_data = pCapacity;free(pCapacity);return res_data;
}

mian.cpp

#include "SysInfo.h"int main()
{SysInfo Info;Info.init_wmi();printf("%s\n", Info.get_os_name().c_str());//Info.uninit_wmi();system("pause");return 0;
}

效果如图所示:
在这里插入图片描述
代码是很早之前写的,用的话需要自己优化一下。


原文出处链接:https://blog.csdn.net/qq_59075481/article/details/142319803。
本文发布于:2024.09.17,修改于:2024.09.17。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/142938.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构初阶】队列接口实现及用队列实现栈超详解

文章目录 1. 概念1. 1 队列底层结构选型1. 2 队列定义 2. 接口实现2. 1 初始化2. 2 判空2. 3 入队列2. 4 出队列2. 5 队尾元素和队头元素和队列元素个数2. 6 销毁2. 7 接口的意义 3. 经典OJ题3. 1 用队列实现栈3. 1. 1 栈的定义3. 1. 2 栈的初始化3. 1. 3 入栈3. 1. 4 出栈3. 1…

微调大模型不再难:LoRA方法带你轻松节省99%的训练成本!

我们之前说大模型有四种玩家&#xff0c;其中前三种都是要做模型训练的。而大部分公司或个人&#xff0c;都是在第二种开源大模型的基础上来做训练。 而这种训练方式又分为两种。一种要么就是从头训练&#xff0c;要么就Fine-tuning接着开源模型来训练&#xff0c;在基座模型已…

【CPP】模板(后篇)

目录 13.1 非类型模板参数13.2 函数模板的特化13.3 类模板的特化13.4 模板的分离编译 这里是oldking呐呐,感谢阅读口牙!先赞后看,养成习惯! 个人主页:oldking呐呐 专栏主页:深入CPP语法口牙 13.1 非类型模板参数 顾名思义,非类型模板参数就是一个模板的参数,只不过不是类型,而…

基于深度学习的图像去雾研究进展

&#x1f31e;欢迎莅临我的个人主页&#x1f448;&#x1f3fb;这里是我专注于深度学习领域、用心分享知识精粹与智慧火花的独特角落&#xff01;&#x1f349; &#x1f308;如果大家喜欢文章&#xff0c;欢迎&#xff1a;关注&#x1f377;点赞&#x1f44d;&#x1f3fb;评论…

个人随想-gpt-o1大模型中推理链的一个落地实现

​首先祝大家中秋节快乐。 最近openai又推出了新的模型openai o1​还有它的mini版。官网的介绍&#xff0c;就是它的推理能力很强&#xff0c;比gpt-4o​有很大的提升。 最近也跟同行在聊这个o1&#xff0c;​看看落地方面有哪些可行性。在我们自己的实验上&#xff0c;把o1用…

JavaScript web API完结篇---多案例

BOM window对象 >包含docment Browser Object Model 定时器–延时函数 之前学的是间歇函数 让代码延迟执行 仅执行一次 setTimeout(回调函数&#xff0c;等待毫秒数) 消除 clearTimeout(timer) > 用于递归时需要进行去除 JS执行机制 单线程 > 一个任务结束&…

【C++笔记】类和对象的深入理解(三)

【C笔记】类和对象的深入理解(三) &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C笔记 文章目录 【C笔记】类和对象的深入理解(三)前言一.日期类的实现1.1声明和定义分离1.2日期类整数1.3日期类整数1.4日期类-整数1.5日期类-日期1.6复用对…

Linux中安装maven

Linux中安装maven 1.下载2.安装3.配置环境变量4.maven相关配置 1.下载 下载地址&#xff1a;https://maven.apache.org/download.cgi 2.安装 指定位置上传压缩包&#xff1a; 解压&#xff1a; tar -zxvf apache-maven-3.9.5-bin.tar.gz修改解压缩后的文件名: mv apac…

Netty笔记09-网络协议设计与解析

文章目录 前言一、协议设计1. 数据格式2. 消息长度3. 编码方式4. 错误处理5. 安全性 二、协议解析1. 消息分隔2. 粘包与半包处理3. 校验机制 三、为什么需要协议&#xff1f;四、redis 协议五、HTTP 协议六、自定义协议要素编解码器&#x1f4a1; 什么时候可以加 Sharable 前言…

【论文阅读】Act3D: 3D Feature Field Transformers for Multi-Task Robotic Manipulation

Abstract 3d感知表示非常适合机器人操作&#xff0c;因为它们很容易编码遮挡并简化空间推理。许多操作任务在末端执行器姿态预测中需要较高的空间精度&#xff0c;这通常需要高分辨率的3d特征网格&#xff0c;这对于处理来说计算成本很高。因此&#xff0c;大多数操作policies…

基于密码的大模型安全治理的思考

文章目录 前言一、大模型发展现状1.1 大模型技术的发展历程1.2 大模型技术的产业发展二、大模型安全政策与标准现状2.1 国外大模型安全政策与标准2.2 我国大模型安全政策与标准前言 随着大模型技术的迅速发展和广泛应用,其安全性问题日益凸显。密码学作为网络空间安全的核心技…

Unity webgl跨域问题 unity使用nginx设置跨域 ,修改请求头

跨域 什么是跨域 跨域是指浏览器因安全策略限制&#xff0c;阻止一个域下的网页访问另一个域下的资源。 一些常见的跨域情况&#xff1a; 协议不同 从 http://example.com 请求 https://example.com。域名不同 从 http://example.com 请求 http://anotherdomain.com。端口不…

《锐捷AP 胖模式配置示例》

目录 WEB配置方式: 1. 登录 AP 管理界面 2. 配置无线服务 3. 配置射频参数 4. 配置 VLAN (如果需要) 5. 配置 IP 地址 6. 其他高级设置(根据需求) 命令行配置: 1. 进入特权模式 2. 进入全局配置模式 3. 配置管理 IP 地址 4. 创建无线 SSID 5. 配置 SSID 加密…

多线程下的共享变量访问数据竞争的问题

多线程下对共享变量的写存在数据竞问题可导致数据与预期不一致。最近在研究race conditions漏洞&#xff0c;用以下python 代码记录一下&#xff0c;以此论证&#xff0c;如下&#xff1a; from concurrent.futures import ThreadPoolExecutor globalNum 5 def test():global…

【深度分析】OpenAI o1是最强的推理模型,却不是最强模型!

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;专注于分享AI全维度知识&#xff0c;包括但不限于AI科普&#xff0c;AI工…

一般在写SQL时需要注意哪些问题,可以提高查询的效率?

很多人写SQL按照自己喜好&#xff0c;没有规则意识&#xff0c;这对于自主查询影响不大&#xff0c;你爱怎么搞就怎么搞&#xff0c;一旦涉及到提交任务或团队共享&#xff0c;就不能乱写了&#xff0c;会浪费资源影响到开发效率&#xff0c;严重的甚至会服务器瘫痪。 提几个关…

python-在PyCharm中使用PyQt5

文章目录 1. 安装 PyQt5 和QtTools2. QtDesigner 和 PyUIC 的环境配置2.1 在 PyCharm 添加 Create Tools2.2 添加 PyUIC 工具 3. 创建ui界面4. 使用python调用ui界面参考文献 1. 安装 PyQt5 和QtTools QT 是最强大的 GUI 库之一&#xff0c;PyQt5 是 Python 绑定 QT5 应用的框…

idea一个窗口打开多个仓库的代码

一、背景 最近新进了一家外包公司&#xff0c;这个项目由于是微服务的&#xff0c;且每个微服务都独立用一个仓库进行代码管理。看项目的时候&#xff0c;我们不能一个窗口&#xff0c;只打开一个仓库代码&#xff0c;那样看起来会非常麻烦&#xff0c;一开始对项目全貌的了解…

Get包中的根组件

文章目录 1. 知识回顾2. 使用方法2.1 源码分析2.2 常用属性 3. 示例代码4. 内容总结 我们在上一章回中介绍了"Get包简介"相关的内容&#xff0c;本章回中将介绍GetMaterialApp组件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 知识回顾 我们在上一章回中已经…

多线程篇(Fork/Join)(持续更新迭代)

目录 知识大纲 一、简介 二、工作窃取算法 三、设计思想 步骤一&#xff1a;分割任务 步骤二&#xff1a;执行任务并合并结果 四、使用 五、异常处理 六、Fork/Join框架的实现原理 1. ForkJoinTask的fork方法实现原理 2. ForkJoinTask的join方法实现原理 七、源码剖…