目录
- 获取系统版本信息
- 代码
获取系统版本信息
通过 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.0
SysInfo::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_PhysicalMemory
double 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.1
if (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。