【问题标题】:Check Windows version检查 Windows 版本
【发布时间】:2010-12-30 03:46:07
【问题描述】:

如果计算机上安装的 Windows 版本是 Windows Vista 及更高版本 (Windows 7),我如何检查 C++?

【问题讨论】:

标签: c++ windows version


【解决方案1】:

此线程中的所有答案都指向您使用GetVersionGetVersionEx 进行此测试,这是不正确。它似乎有效,但它是有风险的。 Windows 操作系统升级的 appcompat 问题的主要来源是基于 GetVersion 结果的编写不佳的测试,带有错误的假设或错误的比较。

进行此测试的正确方法是使用VerifyVersionInfo,而不是GetVersionGetVersionEx

如果您使用的是 VS 2013 编译器工具集和 Windows 8.1 SDK,您可以使用 VersionHelpers.h 并调用 IsWindowsVistaOrGreater

如果你使用 VS 2013 v120_xp 平台工具集针对 Windows XP,你实际上使用的是 Windows 7.1A SDK,所以你需要直接使用VeriyVersionInfo

否则,使用:

bool IsWindowsVistaOrGreater()
{
OSVERSIONINFOEXW osvi = {};
osvi.dwOSVersionInfoSize = sizeof(osvi);
DWORDLONG const dwlConditionMask = VerSetConditionMask(
    VerSetConditionMask(
    VerSetConditionMask(
            0, VER_MAJORVERSION, VER_GREATER_EQUAL),
               VER_MINORVERSION, VER_GREATER_EQUAL),
               VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
osvi.dwMajorVersion = HIBYTE(_WIN32_WINNT_VISTA);
osvi.dwMinorVersion = LOBYTE(_WIN32_WINNT_VISTA);
osvi.wServicePackMajor = 0;

return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
}

此代码可在 Windows 2000 或更高版本上运行,并为您提供可靠的结果。如果您确实需要此测试在 Windows 98 或 Windows ME 上运行 - 并且 - 您使用的编译器工具集足够老,可以在该平台上实际运行,您将执行相同的测试,但使用显式链接而不是隐式链接。 What's in a version number?

此外,在 Windows 8.1 和 Windows 10 上使用 GetVersionGetVersionEx 默认会得到错误的版本。请参阅Manifest Madness

请注意,Windows 10 VerifyVersionInfo 也受制于相同的基于清单的行为(即没有 Windows 10 的 GUID 元素,VVI 的行为就好像操作系统版本号是 6.2 而不是 10.0。也就是说,最真实的-像IsWindowsVistaOrGreaterIsWindows7OrGreaterIsWindows7SP1OrGreaterIsWindows8OrGreater 这样的世界测试即使没有清单也能正常工作。只有当你使用IsWindows8Point1OrGreaterIsWindows10OrGreater 时,基于清单的行为甚至很重要。

另见this堆栈溢出线程。

【讨论】:

  • 我同意VerifyVersionInfo 是 OP 的正确答案。如果我想问这个问题总是正确的:Is the current Windows version at least good enough for my minimum needs?(就像 OP 所做的那样)但我真的想回答的问题是What is the current Windows version?,所以我可以显示它。
  • 纯粹出于遥测/支持显示的目的:在 Windows 桌面应用程序中,您使用 GetVersionEx,抑制弃用警告,将兼容性清单添加到您的 EXE,并且知道有一天它可能会撒谎。对于通用 Windows 平台应用 (UWP),您将使用 AnalyticsInfo。在这两种情况下,都不要将任何逻辑基于版本号的值或执行任何比较。如果是为了电话支持,只需告诉用户运行winver 并将字符串读回给您。
  • 同意!但要回答这样一个简单的问题(过去很容易问),就必须跳过这样的圈子。
  • 总是很容易问“这是什么版本的 Windows?”。更难的问题是(a)提出正确的问题,以及(b)知道如何处理答案。在 90 年代初期,人们在为 Windows 3 编写应用程序时搞砸了这件事,所以要做到这一点总是具有挑战性。见this blog post。对于“Windows 即服务”,这个问题也不再像以前那么有意义了。
  • “was”是重要的词——现在很难。就我而言,目的是显示 Windows 版本,我不会根据值做出任何决定。我知道改变它的完成方式会使提出错误问题变得更加困难。但我问这个问题并不是为了做决定。
【解决方案2】:

使用kernel32.dll中定义的GetVersionEx API函数:

bool IsWindowsVistaOrHigher() {
   OSVERSIONINFO osvi;
   ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
   osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
   GetVersionEx(&osvi);
   return osvi.dwMajorVersion >= 6;
}

【讨论】:

    【解决方案3】:

    类似于检查 Windows NT 版本的其他测试:

    OSVERSIONINFO   vi;
    
    memset (&vi, 0, sizeof vi);
    vi .dwOSVersionInfoSize = sizeof vi;
    GetVersionEx (&vi);
    if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT  &&  vi.dwMajorVersion >= 6)
    

    【讨论】:

    • 为什么平台必须是 32 位的?
    • 64 位 Windows 的平台 ID 为 VER_PLATFORM_WIN32_NT
    • 这不再是真的。除非您将您的应用程序显示为支持 Windows-8.1(及更高版本),否则GetVersionEx 会欺骗您。这在Chuck Walbourn's answer 中有概述。
    • @wallyk - 完全同意微软决策的恼人因素。 VerifyVersionInfo 中的新功能很好用,但没有必要弃用 GetVerionEx
    • 实际上,您在此答案中编写的代码正是 why Microsoft appcompat 团队首先推动弃用 GetVersionEx 的原因。自 Windows 95 以来,主要应用程序已经这样做并且出错了。如果你想进行“你必须这么高才能骑这趟车”检查,这就是 VerifyVersionInfo 旨在稳健和正确地做的事情(这也是VersionHelpers API 包装器使用)。正如我的回答所指出的,您应该知道,从 Windows 10 开始,VVI 具有相同的基于清单的行为,因此您还需要计划添加清单。
    【解决方案4】:

    在 Visual Studio 2013 或更高版本中,您还可以使用新的 Version Helper 函数。

    有许多不同 Windows 版本的方法。示例:

    #include <VersionHelpers.h>
    
    if (!IsWindowsVistaOrGreater())
    {
       MessageBox(NULL, "You need at least Windows Vista", "Version Not Supported", MB_OK);
    }
    

    更多信息here

    【讨论】:

    • 如果使用 VS 2013 和 Windows 8.1 SDK,这是一个很好的选择,只要您不尝试使用实际使用 Windows 7.1A SDK 的 v120_xp 平台工具集来定位 Windows XP . VersionHelpers.h 没有什么特别之处,因为它只是使用 ``VerifyVersionInfo` 的实用程序代码。
    • 这应该被标记为正确答案,因为它是由 Windows SDK 直接提供的。请注意,对于 Windows 10 和 8.1,您需要应用程序清单 msdn.microsoft.com/de-de/library/windows/desktop/…
    【解决方案5】:

    我认为您正在寻找 GetVersionEx 函数。

    【讨论】:

    • 上面的代码是不够的。链接很有帮助。
    • 遗憾的是,GetVersionEx 已被弃用,取而代之的是 VerifyVersionInfo
    【解决方案6】:

    Microsoft support page 为您提供旧版本的详细信息。

    要确定在给定系统上运行的操作系统,需要以下数据:

                  95  98  ME  NT 4  2000  XP
    PlatformID    1   1   1   2     2     2
    Major version 4   4   4   4     5     5
    Minor version 0   10  90  0     0     1
    

    您可以实现代码并在 Vista 和 Windows-7 机器上运行它以检查返回的值。

    要获取操作系统版本信息,请执行以下调用:

    System::OperatingSystem *osInfo = System::Environment::OSVersion;
    

    【讨论】:

      【解决方案7】:

      您可以在 kernel32.dll 中使用 GetVersion() 或 GetVersionEx() 函数。这两个功能仅适用于 Windows 2000 或更高版本。

      如需了解更多信息,请查看http://msdn.microsoft.com/en-us/library/ms724451%28VS.85%29.aspx

      【讨论】:

        猜你喜欢
        • 2017-12-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-23
        • 2013-05-12
        • 2011-08-31
        • 1970-01-01
        • 2013-07-21
        相关资源
        最近更新 更多