原文:http://www.cnblogs.com/VOIP/archive/2011/03/22/1990927.html

Windows API 中有两个函数可以得到系统版本信息GetVersionGetVersionEx

GetVersion这个函数曾经困扰了很多程序员,其本来设计的是在DWORD返回值中用低位的那个字表示MS-DOS的版本号,高位的那个字表示Windows版本号。对于每个字来说,高位字节代表主要版本号,低位字节代表次要版本号。可是因为编写此函数的程序员犯了一个错误,使得此函数返回的Windows版本号颠倒了(即把主要版本号放到了低位字节,而次要版本号放到了高位字节)。当发现此错误的时候已经有很多程序员在使用这个函数了,Microsoft只好将错就错,直接把原来的API文档给改了过来。

为了解决GetVersion带来的问题,Microsoft后来开发了一个新的函数GetVersionEx,用它能够得到更详细的Windows系统的版本信息,下面我就写写GetVersionEx的使用方法。

函数原型:

BOOL GetVersionEx(POSVERSIONINFO pVersionInformation);

我们先来看看OSVERSIONINFOEX这个结构:

typedef struct {

DWORD dwOSVersionInfoSize;       //在使用GetVersionEx之前要将此初始化为结构的大小

DWORD dwMajorVersion;               //系统主版本号

DWORD dwMinorVersion;               //系统次版本号

DWORD dwBuildNumber;               //系统构建号

DWORD dwPlatformId;                  //系统支持的平台(详见附1)

TCHAR szCSDVersion[128];          //系统补丁包的名称

WORD wServicePackMajor;            //系统补丁包的主版本

WORD wServicePackMinor;            //系统补丁包的次版本

WORD wSuiteMask;                      //标识系统上的程序组(详见附2)

BYTE wProductType;                    //标识系统类型(详见附3)

BYTE wReserved;                         //保留,未使用

} OSVERSIONINFOEX, *POSVERSIONINFOEX;

这个结构在Windows 2000后出现,老版本的OSVERSIONINFO结构没有wServicePackMajor、wServicePackMinor、wSuiteMask、wProductType和wReserved这几个成员。

接着在调用函数之前先初始化结构的大小:

OSVERSIONINFOEX os;

os.dwOSVersionInfoSize=sizeof(os);

函数返回值为TRUE表示成功:

if(!GetVersionEx((OSVERSIONINFO *)&os))

{

return FALSE;

}

函数调用成功以后就可以通过OSVERSIONINFOEX来查看系统的版本信息了。

下面是一个通过系统版本来判断操作系统名称的例子:

CString getSystemName()

{

SYSTEM_INFO info;                                   //用SYSTEM_INFO结构判断64位AMD处理器
    GetSystemInfo(&info);                               //调用GetSystemInfo函数填充结构
    OSVERSIONINFOEX os;
    os.dwOSVersionInfoSize=sizeof(OSVERSIONINFOEX); 
    if(GetVersionEx((OSVERSIONINFO *)&os))                  
    {
        CString vname;

//下面根据版本信息判断操作系统名称

switch(os.dwMajorVersion){                        //判断主版本号
            case 4:
                switch(os.dwMinorVersion){                //判断次版本号
                    case 0:
                        if(os.dwPlatformId==VER_PLATFORM_WIN32_NT)
                            vname=_T("Microsoft Windows NT 4.0");                //1996年7月发布
                        else if(os.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)
                            vname=_T("Microsoft Windows 95");
                        break;
                    case 10:
                        vname=_T("Microsoft Windows 98");
                        break;
                    case 90:
                        vname=_T("Microsoft Windows Me");
                        break;
                }
                break;
            case 5:
                switch(os.dwMinorVersion){               //再比较dwMinorVersion的值
                    case 0:
                        vname=_T("Microsoft Windows 2000");                    //1999年12月发布
                        break;
                    case 1:
                        vname=_T("Microsoft Windows XP");                    //2001年8月发布
                        break;
                    case 2:
                        if(os.wProductType==VER_NT_WORKSTATION && /

info.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)

vname=_T("Microsoft Windows XP Professional x64 Edition");
                        else if(GetSystemMetrics(SM_SERVERR2)==0)
                            vname=_T("Microsoft Windows Server 2003");        //2003年3月发布
                        else if(GetSystemMetrics(SM_SERVERR2)!=0)
                            vname=_T("Microsoft Windows Server 2003 R2");
                        break;
                }
                break;
            case 6:
                switch(os.dwMinorVersion){
                    case 0:
                        if(os.wProductType==VER_NT_WORKSTATION)
                            vname=_T("Microsoft Windows Vista");
                        else
                            vname=_T("Microsoft Windows Server 2008");          //服务器版本
                        break;
                    case 1:
                        if(os.wProductType==VER_NT_WORKSTATION)
                            vname=_T("Microsoft Windows 7");
                        else
                            vname=_T("Microsoft Windows Server 2008 R2");
                        break;
                }
                break;
            default:
                vname=_T("未知操作系统");
        }
        return vname;
    }
    else
        return _T("");

}

以上只能判断操作系统的名称,那如何判断它是什么版本的呢(如Home版或Professional版)。

下面这个函数就返回具体的版本名称

CString getVersionMark()

{

OSVERSIONINFOEX os;
    os.dwOSVersionInfoSize=sizeof(OSVERSIONINFOEX);
    if(GetVersionEx((OSVERSIONINFO *)&os)){
        CString vmark;

switch(os.dwMajorVersion){                //先判断操作系统版本
            case 5:
                switch(os.dwMinorVersion){
                    case 0:                  //Windows 2000
                        if(os.wSuiteMask==VER_SUITE_ENTERPRISE)
                            vmark=_T("Advanced Server");
                        break;
                    case 1:                  //Windows XP
                        if(os.wSuiteMask==VER_SUITE_EMBEDDEDNT)
                            vmark=_T("Embedded");
                        else if(os.wSuiteMask==VER_SUITE_PERSONAL)
                            vmark=_T("Home Edition");
                        else
                            vmark=_T("Professional");
                        break;
                    case 2:
                        if(GetSystemMetrics(SM_SERVERR2)==0 && /

os.wSuiteMask==VER_SUITE_BLADE)  //Windows Server 2003
                            vmark=_T("Web Edition");
                        else if(GetSystemMetrics(SM_SERVERR2)==0 && /

os.wSuiteMask==VER_SUITE_COMPUTE_SERVER)
                            vmark=_T("Compute Cluster Edition");
                        else if(GetSystemMetrics(SM_SERVERR2)==0 && /

os.wSuiteMask==VER_SUITE_STORAGE_SERVER)
                            vmark=_T("Storage Server");
                        else if(GetSystemMetrics(SM_SERVERR2)==0 && /

os.wSuiteMask==VER_SUITE_DATACENTER)
                            vmark=_T("Datacenter Edition");
                        else if(GetSystemMetrics(SM_SERVERR2)==0 && /

os.wSuiteMask==VER_SUITE_ENTERPRISE)
                            vmark=_T("Enterprise Edition");
                        else if(GetSystemMetrics(SM_SERVERR2)!=0 &&  /

os.wSuiteMask==VER_SUITE_STORAGE_SERVER)

vmark=_T("Storage Server");
                        break;
                }
                break;
            case 6:
                switch(os.dwMinorVersion){
                    case 0:
                        if(os.wProductType!=VER_NT_WORKSTATION && /

os.wSuiteMask==VER_SUITE_DATACENTER) 
                            vmark=_T("Datacenter Server");
                        else if(os.wProductType!=VER_NT_WORKSTATION &&  /

os.wSuiteMask==VER_SUITE_ENTERPRISE)
                            vmark=_T("Enterprise");
                        else if(os.wProductType==VER_NT_WORKSTATION && /

os.wSuiteMask==VER_SUITE_PERSONAL)  //Windows Vista

vmark=_T("Home");
                        break;
                }
                break;
            default:
                vmark=_T("");
        }
        return vmark;
    }
    else
        return _T("");

}

另外,操作系统的补丁包名称也可以从szCSDVersion直接获取。

程序编译出来后大家可以用不同版本的兼容模式运行这个程序,来检测结果是不是正确,兼容模式会欺骗GetVersionEx这些API函数,拿Windows 98 兼容模式来说,程序会以为自己是在Windows 98 上运行。

有什么问题请给我留言,如果在本页面下发没有看到有留言请刷新一下页面。

附1:dwPlatformId的值:

VER_PLATFORM_WIN32s (Win32s),

VER_PLATFORM_WIN32_WINDOWS (Windows 95/Windows 98),

VER_PLATFORM_WIN32_NT (Windows NT/Windows 2000),

VER_PLATFORM_WIN32_CEHH (Windows CE).

附2:wSuiteMask的值:

VER_SUITE_SMALLBUSINESS,

VER_SUITE_ENTERPRISE,

VER_SUITE_BACKOFFICE,

VER_SUITE_COMMUNICATIONS,

VER_SUITE_TERMINAL,

VER_SUITE_SMALLBUSINESS_RESTRICTED,

VER_SUITE_EMBEDDEDNT,

VER_SUITE_DATACENTER.

附3:wProductType的值:

VER_NT_WORKSTATION,

VER_NT_SERVER,

VER_NT_DOMAIN_CONTROLLER.

GetVersion和GetVersionEx的更多相关文章

  1. WindowsAPI使用详解——GetVersion|GetVersionEx 获取操作系统版本和名称

      Windows API 中有两个函数可以得到系统版本信息:GetVersion和GetVersionEx.      GetVersion这个函数曾经困扰了很多程序员,其本来设计的是在DWORD返 ...

  2. NTDLL未文档化函数RtlGetNtVersionNumbers获取操作系统版本

    作为新手,对获取操作系统版本号好奇过,因为曾经假象过一个场景:自己的程序在windows xp环境下编译,在windows 2003, windows 7,windows 8是否需要提权或者兼容处理, ...

  3. C# 获取并判断操作系统版本,解决Win10、 Windows Server 2012 R2 读取失败的方案

    Windows 8.1, Win10之后,通过GetVersion and GetVersionEx 方法获取WIndows操作系统版本号的功能需要添加manifest文件后才能查找到,不然的话会查找 ...

  4. API得到Windows版本

    API得到Windows版本 /** * Windows Version * https://msdn.microsoft.com/en-us/library/windows/desktop/dn48 ...

  5. 也谈如何获取真实正确的 Windows 系统版本号

    关于 GetVersion 系列接口 关于如何获取 Windows 系统版本号的话题,网上已经有了太多的帖子.但个人觉得总结的都不尽全面,或者没有给出比较稳定的解决方案. 众所周知,获取 Window ...

  6. 推断Windows版本号新方法

    曾经在代码中推断用户的Windows操作系统版本号都是通过GetVersion或GetVersionEx获取版本号号,然后比較. 今天偶然发如今新的Visual Studio提供了新的函数来推断系统版 ...

  7. 获取windows版本信息的做法

    作者:朱金灿 来源:http://blog.csdn.net/clever101 个人不建议用 GetVersion 或GetVersionEx 之类的 API 来获取系统版本号.注意微软也说过,这个 ...

  8. 读取注册表获取Windows系统XP/7/8/10类型(使用wcscmp比较wchar[]内容)

    很多方案是采用GetVersion.GetVersionEx这两个API来查询操作系统的版本号来判断当前的操作系统是Windows系列中的哪个,在Win10没有出现前,这种方法是行的通的,但是Win1 ...

  9. Delphi7所使用的WinAPI大全(摘自VCL源码,一共1200个函数)

    经过我整理的,去掉了A和W的重复.虽然没写注释,但以后要一个一个研究.有这些WINAPI就够用了. kernel32 = 'kernel32.dll'; gdi32 = 'gdi32.dll'; us ...

随机推荐

  1. JavaSwing概述

    GUI(Graphic User Interface)为程序提供图形界面,它最初的设计目的是构建一个通用的GUI,使其能在所有平台上运行.在Java1.0中基础类AWT(Abstract Window ...

  2. myEclipse卡顿解决

    1 .关闭MyEclipse的自动validation windows > perferences > myeclipse > validation 将Build下全部勾取消 如果你 ...

  3. 补充ABP Zero集成微信小程序登陆的BUG修复部分

    感谢园友 @turingguo 发布的 https://www.cnblogs.com/turingguo/p/9019026.html  文章,详细介绍了ABP Zero集成微信小程序登陆的实现过程 ...

  4. 1.python学习计划

    1.python学习 第一次使用博客园作为学习记录日志,希望能在这里记录自己的学习点滴. 慢慢去挖掘它的强大功能吧

  5. Oracle 事务操作

    在看本文之前,请确保你已经了解了Oracle事务和锁的概念即其作用,不过不了解,请参考数据库事务的一致性和原子性浅析和Oracle TM锁和TX锁 1.提交事务 当执行使用commit语句可以提交事务 ...

  6. CentOS6.4 安装Maven及Nexus仓库代理

    本文安装的apache-maven-3.5.0-bin.tar.gz,nexus-2.9.0-04-bundle.tar.gz 1.由于网络并不是特别好我这边是通过本地下载过来,通过sftp上传至Ce ...

  7. orcale 之 pl/sql

    基本结构 不多说直接来看下它的结构: DECLARE -- 此处声明一些变量.常量.或者用户自定的数据类型 -- 这一部分是可选的,如果不需要可以不写 BEGIN -- 程序的主体,这里可以写一些合法 ...

  8. django允许跨域请求配置

    django允许跨域请求配置 下载corsheader pip install django-cors-headers 修改setting.py中配置 在INSTALLED_APPS中增加corshe ...

  9. 部分linux命令

    计算机网络的主要优点是能够实现资源和信息的共享,并且用户可以远程访问信息.Linux提供了一组强有力的网络命令来为用户服务,这些工具能够帮助用户登录到远程计算机上.传输文件和执行远程命令等. 本章介绍 ...

  10. SSRS Report Knowledge Base

    1. 获取Textbox的值,根据Textbox值更改单元格颜色 Textbox值:=ReportItems!Textbox1.Value 当前单元格的值:=Me.Value =IIF(ReportI ...