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

news2024/11/23 16:48:45

目录

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

获取系统版本信息

通过 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。

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

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

相关文章

学成在线练习(HTML+CSS)

准备工作 项目目录 内部包含当前网站的所有素材&#xff0c;包含 HTML、CSS、图片、JavaScript等等 1.由于元素具有一些默认样式&#xff0c;可能是我们写网页过程中根本不需要的&#xff0c;所有我们可以在写代码之前就将其清除 base.css /* 基础公共样式&#xff1a;清除…

如何用MATLAB计算多边形的几何中心

在MATLAB中&#xff0c;计算多边形的几何中心&#xff08;又称质心或重心&#xff09;可以通过以下步骤实现。假设你有一个多边形&#xff0c;其顶点按照顺时针或逆时针顺序排列在一个矩阵中。具体步骤如下&#xff1a; 定义多边形顶点&#xff1a;首先&#xff0c;你需要将多边…

FPGA随记——状态机

1. 概念 状态机&#xff08;State Machine&#xff09;&#xff1a; 有限状态机&#xff08;Finite State Machine&#xff0c;简称FSM&#xff09; 在有限个状态之间按一定规律转换的时序电路。 2 状态机模型 组成元素&#xff1a;输入、状态、状态转移条件、输出&#xff…

BSN六周年:迈向下一代互联网

当前&#xff0c;分布式技术作为现代计算机科学和信息技术的重要组成部分&#xff0c;在云计算、区块链等技术的推动下&#xff0c;正以多样化的形式蓬勃发展。 ​而区块链作为一种特殊的分布式系统&#xff0c;近年来也在各个领域得到了广泛关注。通过在区块链上运行智能合约…

情系河北 缘聚苏州——2024苏州河北同乡迎国庆贺中秋大团圆联谊活动圆满举办

金秋送爽&#xff0c;月朗中天。9月15日晚&#xff0c;由苏州市河北商会志愿者工作委员会牵头&#xff0c;苏州河北以及各地市老乡群联合主办的第二届“情系河北 缘聚苏州”--2024年苏州河北同乡迎国庆贺中秋大团圆联谊活动在香雪海饭店&#xff08;吴中大道店&#xff09;二楼…

C++自学笔记35(文件操作)

讲解常见文件操作函数 fopen FILE* fp fopen&#xff08;char const* _FileName,char const* _Mode&#xff09; 第一个参数&#xff1a;文件名&#xff0c;字符串表示 第二个参数&#xff1a;文件打开模式3种 1.rb&#xff08;read birary&#xff09;&#xff1a;读文件…

【算法】动态规划—编辑距离

题目 给你两个单词 word1 和 word2&#xff0c; 请返回将 word1 转换成 word2 所使用的最少操作数 。 你可以对一个单词进行如下三种操作&#xff1a; 插入一个字符删除一个字符替换一个字符 思路分析 编辑距离问题就是给定两个字符串 s1 和 s2&#xff0c;只能用三种操作…

STM32外设-0.96寸OLED显示屏

江科大OLED教程&#xff1a;01-快速上手&#xff08;上集&#xff09;_哔哩哔哩_bilibili 01 0.96寸OLED显示屏原理 1.1 0.96寸OLED显示屏简介 适用器件&#xff1a; 0.96寸OLED显示屏&#xff08;驱动芯片&#xff1a;SSD1306 / SSD1315&#xff09; 1.3寸OLED显示屏&…

针对国内AIGC市场,国内目前出台了那些法律法规?

针对国内AIGC市场&#xff0c;特别是AI生成与合成内容方面&#xff0c;中国已经出台了一系列法律法规来规范其发展和应用。 图片源自“央视新闻” 以下是一些主要的法律法规&#xff1a; 一、国家层面的法律法规 《中华人民共和国网络安全法》 施行时间&#xff1a;2017年6月…

【课程学习】信号检测与估计II

b站 文章目录 1-概述贝叶斯方法1-概述 线性、正交、平稳、高斯 研究线性模型,采用正交化方法,假设信号平稳,考虑信号的统计特性是高斯的。 本学期考虑,非线性、非正交、非平稳、非高斯。 阵列处理 1980-1990 MUSIC 稀疏性 2006-2012 LASS 时频分析 1995-2000 小波 贝叶斯 2…

echarts 自定义标注样式自定义tooltip弹窗样式

文章目录 1. 实现根据经纬度自定义标注图片样式2. 实现鼠标悬浮标注自定义弹窗样式内容 1. 实现根据经纬度自定义标注图片样式 设置 symbol 属性为 image://${require("/assets/img/dataView/point.png")} 图片地址即可&#xff0c;注意前面跟 image:// 特有的写法b…

搭建一个基于角色的权限验证框架

说明&#xff1a;基于角色的权限验证&#xff08;Role-Based Access Control&#xff0c;RBAC&#xff09;框架&#xff0c;是目前大多数服务端的框架。本文介绍如何快速搭建一个这样的框架&#xff0c;不用Shiro、Spring Security、Sa-Token这样的“大框架”实现。 RBAC 基于…

【图像匹配】基于‌墨西哥帽小波(Marr小波)算法的图像匹配,matlab实现

博主简介&#xff1a;matlab图像代码项目合作&#xff08;扣扣&#xff1a;3249726188&#xff09; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 本次案例是基于‌墨西哥帽小波&#xff08;Marr小波&#xff09;算法的图像匹配&#xff0c;用…

09_Python流程控制_分支

流程控制 流程控制是管理程序执行顺序的重要组成部分。分支&#xff08;也称为条件语句&#xff09;是流程控制的一种形式&#xff0c;它允许程序根据某些条件的真假来选择执行不同的代码路径。 顺序结构&#xff1a;按部就班执行选择结构&#xff1a;根据条件不同执行循环结…

项目实训:CSS基本布局理解——WEB开发系列38

对CSS学习已经接近尾声&#xff0c;下面你可以对以下两道“小卡拉米”测试进行测试下CSS理解程度。 题 1&#xff1a;基于栅格布局的现代博客首页设计 题目要求&#xff1a; 创建一个博客首页布局&#xff0c;包含一个顶部导航栏、一个主要的内容区域&#xff08;左侧为博客文…

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

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

使用 PHPstudy 建立ThinkPHP8 本地集成环境

安装Composer 下载地址&#xff1a;https://getcomposer.org/Composer-Setup.exehttps://getcomposer.org/Composer-Setup.exe 打开PHPstudy创建网站&#xff1a; cmd终端进入PHPstudy www根目录下&#xff1a; 执行代码&#xff1a;cd phpstudy www 根目录地址 cd C:\phpst…

甲骨文发布全球首个采用英伟达™(NVIDIA®)Blackwell GPU的Zettascale人工智能超级计算集群

甲骨文公司宣布推出全球首个Zettascale云计算集群。 该集群配备了令人印象深刻的 131,072 个英伟达Blackwell GPU&#xff0c;能够提供 2.4 ZettaFLOPS 的峰值性能。 这一强大的人工智能基础设施使企业能够以更大的灵活性和主权处理大规模人工智能工作负载。 Oracle云计算基础…

算法_宽度优先搜索解决FloodFill---持续更新

文章目录 前言什么是FloodFill算法图像渲染题目要求题目解析代码如下 岛屿数量题目要求题目解析代码如下 岛屿的最大面积题目要求题目解析代码如下 被围绕的区域题目要求题目解析代码如下 前言 本文将会向你介绍宽度优先搜索解决FloodFill算法相关题型&#xff1a;图像渲染、岛…

2019-2023(CSP-J)选择题真题解析

1&#xff0c;了解的知识 中国的国家顶级域名是&#xff08; &#xff09;【2019年CSP-J初赛选择题第一题】 A…cn B…ch C…chn D…china 【答案】&#xff1a;A 以下哪个奖项是计算机科学领域的最高奖&#xff1f;&#xff08; &#xff09;【2019年CSP-J初赛选择题第…