使用C++获取Windows操作系统版本

8
我需要获取我的Windows8系统的OS版本(版本应为NT 6.2),以在C++应用程序中使用。我尝试使用GetVersion函数调用GetVersion,但它返回了一个原始值,如602931718。是否有办法可以像这里列出的那样获取版本?或者如何将此原始值转换为可读形式?

4
据我所理解,你链接的页面正好有你所需的内容... - Borgleader
如果你愿意使用许多 if 语句,你可能可以像这样做些什么。 - Javia1492
4
为什么现在的新手程序员只读文档页面的前六个单词?请阅读_全部内容_。你需要的一切都在那里。天啊。 - Lightness Races in Orbit
@Jackz 在页面底部的评论中。 - Borgleader
来自微软:对于所有平台,低位字包含操作系统的版本号。该字的低位字节指定主要版本号,以十六进制表示。高位字节指定次要版本(修订)号,以十六进制表示。高位比特为零,接下来的7个比特表示构建号,低位字节为5。 - Javia1492
显示剩余3条评论
5个回答

14
注意,函数GetVersion和GetVersionEx已被弃用。这也反映在它们的文档页面上(此处的文本来自于GetVersion):
“随着Windows 8.1的发布,GetVersion API的行为已经发生了变化,返回操作系统版本的值也发生了变化。GetVersion函数返回的值现在取决于应用程序的清单文件。”

13
不幸的是,“替换”方法VerifyVersionInfo在语义上并不扮演相同的角色。它回答的问题是“当前版本足够好吗?”,而不是“当前版本是什么?” - Jesse Chisholm
3
还有获取当前版本的方法吗? - mbaros
4
在 Windows 10 中,VerifyVersionInfo 函数已被弃用 - Stevoisiak
4
你可以使用内核函数RtlGetVersion来获取正确的版本,而不需要依赖应用程序的清单文件中的信息。详细信息请参考https://dev59.com/sFoV5IYBdhLWcg3wN8hD#36545162。 - frido

3
  1. 我尝试过上面的答案,似乎无法正确获取8以上的Windows操作系统版本。
  2. 因此,在漫长的奋斗中,我找到了源代码示例,并能够正确返回版本。
  3. 通过使用'GetProcAddress',获取操作系统版本真的很容易。此外,我尝试了下面的示例链接,对我来说效果很好。

获取操作系统版本c ++源代码

  1. 如果有人在获取操作系统版本方面遇到问题,请随时分享您的想法。

这对我非常有效,谢谢。只是不知道为什么还需要包含 #include <winternl.h>,除了您的示例之外。 - Skewjo

2

我在Windows 7上使用Dev-C++编译了这个程序。该程序与此问题的第一个答案相同,但在Dev-C++中,调用GetVersionEx()时需要对OSVERSIONINFOEX信息进行类型转换。因此,以下是代码:

#include<windows.h>
#include<stdio.h>
int main()
{
     OSVERSIONINFOEX info;
     ZeroMemory(&info, sizeof(OSVERSIONINFOEX));
     info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
     GetVersionEx((LPOSVERSIONINFO)&info);//info requires typecasting

     printf("Windows version: %u.%u\n", info.dwMajorVersion, info.dwMinorVersion);

}

1

您是否查看过GetVersionEx()函数和OSVERSIONINFOEX结构?

可能的用法:

void print_os_info()
{
    OSVERSIONINFOEX info;
    ZeroMemory(&info, sizeof(OSVERSIONINFOEX));
    info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);

    GetVersionEx(&info);

    printf("Windows version: %u.%u\n", info.dwMajorVersion, info.dwMinorVersion);
}

我不明白,NT是什么意思。根据MSDN的说法:

Version table

自 Windows XP 起,所有版本都隐含为 NT 版本。如果想要针对服务器版本进行测试,请检查 info.wProductType 的值:
if(info.dwMajorVersion == 6)
{
    if (info.dwMinorVersion == 0)
    {
        if (info.wProductType == VER_NT_WORKSTATION)
            //Windows Vista;
        else
            //Windows Server 2008
    }
    else if (info.dwMinorVersion == 1)
    {
        if (info.wProductType == VER_NT_WORKSTATION)
            //Windows 7
        else
            //Windows Server 2008 R2
    }
    else if (...) //etc...
}

还有一件事:你也可以检查info.dwBuildNumber的值。允许的值之一是VER_PLATFORM_WIN32_NT


15
自Windows 8.1起,此功能已被弃用。 - Daniel W.

-3

如果你想让它更方便,可以尝试将其转换为浮点数而不是检查两个整数:

double GetOsVersion() {
    OSVERSIONINFOEX info;
    ZeroMemory(&info, sizeof(OSVERSIONINFOEX));
    info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
    GetVersionEx(&info);

    double version;

    version = info.dwMajorVersion 
            + (info.dwMinorVersion / 10.0)
            - (info.wProductType == VER_NT_WORKSTATION) ? 0.5 : 0.0;

    return ver;
}

// Windows 10             : 10.0
// Windows 8.1            : 6.3
// Windows 8.0            : 6.2
// Windows Server 2012    : 6.15
// Windows 7              : 6.1
// Windows Server 2008 R2 : 6.05
// Windows Vista          : 6.0

关于添加创建浮点版本的最后一个术语,具体来说,“使用VER_NT_WORKSTATION”,我对服务器版本是否应该为+0.05或-0.05,或与非服务器版本相同进行了一些辩论。我将把这个决定留给你来决定。

4
这是错误的建议,因为使用“double”类型无法精确表示6.3、6.2或6.05,所以它们将近似为稍微小一些或大一些的值。例如,在Windows 7上,像GetOsVersion()>=6.1这样的测试可能会失败。 - sam hocevar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接