当前位置: 首页 > news >正文

【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.mrgr.cn/news/29038.html

相关文章:

  • 速盾:cdn 支持 php 吗?
  • 2分钟在阿里云ECS控制台部署个人应用(图文示例)
  • 【机器学习】机器学习中用到的高等数学知识
  • Spring IOC 和Spring Aop
  • 【Git】Git Clone 指定自定义文件夹名称:详尽指南
  • 刷错学校了—河工大oj 1051- 1072 做题笔记
  • 网络安全-利用 Apache Mod CGI
  • LeetCode_sql_day26(184,1549,1532,1831)
  • Vue的使用
  • [go] 命令模式
  • 第159天:安全开发-Python-协议库爆破FTPSSHRedisSMTPMYSQL等
  • ArrayList的扩容机制
  • Redis 篇-初步了解 Redis 持久化、Redis 主从集群、Redis 哨兵集群、Redis 分片集群
  • java注解
  • c++概念
  • Linux进程等待 | 程序替换
  • mysql学习教程,从入门到精通,SQL 更新数据(UPDATE 语句)(17)
  • 右值生命周期的延长
  • linux gcc 静态库的简单介绍
  • 代码随想录打卡Day35
  • 计数服务怎么设计?
  • 【读书】原则
  • 牛客周赛 Round 60(A,B,C,D,E,F)
  • 等保测评:企业如何建立安全的开发环境
  • MyBatis 源码解析:Mapper 文件加载与解析
  • C++知识点示例代码助记