【问题标题】:C++ Check if Windows 10C++ 检查是否是 Windows 10
【发布时间】:2015-08-25 00:42:17
【问题描述】:

我正在针对特定操作系统制作应用程序,但我似乎无法缩小 Windows 10 的范围,它以 Windows 8 的形式出现。我已经在 Window 10 Pro 上对其进行了测试,结果是 Major: 6 Min:2。还有其他方法可以更有效地检查它是否是 Windows 10?

编辑:发现一个正常工作的 API RtlGetVersion() 适用于所有操作系统!

#include "windows.h"
#include <iostream>
using namespace std;
BOOL EqualsMajorVersion(DWORD majorVersion)
{
OSVERSIONINFOEX osVersionInfo;
::ZeroMemory(&osVersionInfo, sizeof(OSVERSIONINFOEX));
osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
osVersionInfo.dwMajorVersion = majorVersion;
ULONGLONG maskCondition = ::VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL);
return ::VerifyVersionInfo(&osVersionInfo, VER_MAJORVERSION, maskCondition);
}
BOOL EqualsMinorVersion(DWORD minorVersion)
{
OSVERSIONINFOEX osVersionInfo;
::ZeroMemory(&osVersionInfo, sizeof(OSVERSIONINFOEX));
osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
osVersionInfo.dwMinorVersion = minorVersion;
ULONGLONG maskCondition = ::VerSetConditionMask(0, VER_MINORVERSION, VER_EQUAL);
return ::VerifyVersionInfo(&osVersionInfo, VER_MINORVERSION, maskCondition);
}
int main()
{
    if (EqualsMajorVersion(7) && EqualsMinorVersion(1))
        printf("Maj:7 Min:1");
    else if (EqualsMajorVersion(7) && EqualsMinorVersion(0))
        printf("Maj:7 Min:0");
    else if (EqualsMajorVersion(6) && EqualsMinorVersion(7))
        printf("Maj:6 Min:7");
    else if (EqualsMajorVersion(6) && EqualsMinorVersion(6))
        printf("Maj:6 Min:6");
    else if (EqualsMajorVersion(6) && EqualsMinorVersion(5))
        printf("Maj:6 Min:5");
    else if (EqualsMajorVersion(6) && EqualsMinorVersion(4))
        printf("Maj:6 Min:4");
    else if (EqualsMajorVersion(6) && EqualsMinorVersion(3))
        printf("Maj:6 Min:3");
    else if (EqualsMajorVersion(6) && EqualsMinorVersion(2))
        printf("Maj:6 Min:2");
    else if (EqualsMajorVersion(6) && EqualsMinorVersion(1))
        printf("Maj:6 Min:1");
    else if (EqualsMajorVersion(6) && EqualsMinorVersion(0))
        printf("Maj:6 Min:0");
    else if (EqualsMajorVersion(5) && EqualsMinorVersion(2))
        printf("Maj:5 Min:2");
    else if (EqualsMajorVersion(5) && EqualsMinorVersion(1))
        printf("Maj:5 Min:1");
    else
        printf("OS not on list...");
    getchar();
}

【问题讨论】:

  • 需要考虑的事情:微软表示,较新版本的 Windows 将模仿旧版本,因为程序清单声称它是用它构建的。无论是通过兼容性库还是虚拟机来完成,未来都是开放的。但正因为如此,我不确定您是否可以再从应用程序中找到操作系统版本。
  • 使用GetVersionEx怎么样?这也允许你缓存结构,你只需要调用一次。
  • 嘿,我找到了我记得的内容:“未针对 Windows 8.1 或 Windows 10 显示的应用程序将返回 Windows 8 操作系统版本值 (6.2)。一旦针对给定操作系统版本显示应用程序,GetVersionEx将始终返回应用程序在未来版本中体现的版本。” -- msdn.microsoft.com/en-us/library/windows/desktop/…
  • 我想知道你打算用RtlGetVersion 做什么。在未来的 2025 版本的 Windows 中,如果微软按照他们的计划进行,你的程序将在虚拟机中运行。询问真实版本的 Windows 就像询问虚拟机的主机操作系统一样。毫无意义的信息,因为没有任何 API、设备驱动程序、文件系统等看起来像 2025 年的 Windows。
  • @ZanLynx 一个原因可能是 显示 当前的 Windows 版本,而不是忍受 GetVersionEx 提供的“优点”,尤其是在弃用警告和“唯一" 编号对最终用户确实没有帮助。我可以理解 MS 对人们得到版本 checks 错误感到恼火。但是检索 Windows 版本的用途比版本检查更多。

标签: c++ windows operating-system windows-10


【解决方案1】:

这很讽刺,但是......

BOOL WINAPI IsWindows10OrGreater(void);

文档here.

编辑:来自 Redmond 的天才们似乎在思考原型时遇到了问题,或者换句话说,OP 得到了 cmets 中所述的未定义符号错误。还有这个功能:

BOOL WINAPI IsWindowsVersionOrGreater(
    WORD wMajorVersion,
    WORD wMinorVersion,
    WORD wServicePackMajor
);

而且,对于 Windows 10,wMajorVersionwMinorVersionwServicePackMajor 似乎分别是 1000

该函数的文档here

第二次编辑:这是官方的:IsWindowsVersionOrGreater()GetVersionEx() 从 8.1 开始被破坏。始终使用IsWindowsXXXOrGreater(),其中XXX 可以是XPXPSP1XPSP2XPSP3VistaVistaSP1VistaSP274、74 987654345@、8Point110Server

【讨论】:

  • API 看起来不错但没有定义,我使用的是 VS2015 编译器平台,它仍然无法正常工作。
  • 他是否包含 VersionHelpers.h ?文档说你必须使用那个头文件。
  • 是的,我是 VersionHelpers.h,但它仍然没有在 VS 2015 中声明?我还查看了您的“针对 Windows 的应用程序”。
  • IsWindowsVersionOrGreater() 在 Win10 系统中给出 false。 GetVersionEx 提供主要和次要版本为 6 和 2。两者都不起作用
  • @testit:不确定 Win10 的功能是否损坏。但是,it definitively can't be major version 6 如果这些功能确实有效。
【解决方案2】:

以下对我有用:

.
.
.
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
.
.
.

typedef void (WINAPI * RtlGetVersion_FUNC) (OSVERSIONINFOEXW *);
BOOL GetVersion(OSVERSIONINFOEX * os) {
    HMODULE hMod;
    RtlGetVersion_FUNC func;
#ifdef UNICODE
    OSVERSIONINFOEXW * osw = os;
#else
    OSVERSIONINFOEXW o;
    OSVERSIONINFOEXW * osw = &o;
#endif

    hMod = LoadLibrary(TEXT("ntdll.dll"));
    if (hMod) {
        func = (RtlGetVersion_FUNC)GetProcAddress(hMod, "RtlGetVersion");
        if (func == 0) {
            FreeLibrary(hMod);
            return FALSE;
        }
        ZeroMemory(osw, sizeof (*osw));
        osw->dwOSVersionInfoSize = sizeof (*osw);
        func(osw);
#ifndef UNICODE
        os->dwBuildNumber = osw->dwBuildNumber;
        os->dwMajorVersion = osw->dwMajorVersion;
        os->dwMinorVersion = osw->dwMinorVersion;
        os->dwPlatformId = osw->dwPlatformId;
        os->dwOSVersionInfoSize = sizeof (*os);
        DWORD sz = sizeof (os->szCSDVersion);
        WCHAR * src = osw->szCSDVersion;
        unsigned char * dtc = (unsigned char *)os->szCSDVersion;
        while (*src)
            * Dtc++ = (unsigned char)* src++;
        *Dtc = '\ 0';
#endif

    } else
        return FALSE;
    FreeLibrary(hMod);
    return TRUE;
}

.
.
.

//check win10
void mymethod() {

OSVERSIONINFOEX os;

    if (GetVersion(&os) == TRUE && os.dwMajorVersion == 10)
    {
        isWin10 = TRUE;
    }

}

参考。 : (http://yamatyuu.net/computer/program/vc2013/rtlgetversion/index.html)

【讨论】:

  • 这个实现有一点缺陷,请看stackoverflow.com/questions/36543301/…中接受的答案。一个例子是 RtlGetVersion: is not void 的返回类型,以及 OSVERSIONINFOEXW/A 上的指针的技巧是不干净的。
  • 我已经搜索了很多获取操作系统版本的方法(而不仅仅是它是否高于特定版本)。我需要完整的细节,例如内部版本号、主要和次要版本,这是唯一对我有用的代码!谢谢!
  • 您的代码中存在大小写问题Dtc / dtc
【解决方案3】:

更新:检查 win7、win8.1 和 win10。现在一切都决定了。所以代码:

#include <windows.h>
#include <VersionHelpers.h>
#include <string>

std::string getWinVerion() {

OSVERSIONINFO info;
ZeroMemory(&info, sizeof(OSVERSIONINFO));
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

GetVersionEx(&info);

std::string version = std::to_string(info.dwMajorVersion);
version.append(".").append(std::to_string(info.dwMinorVersion));

if (IsWindows7SP1OrGreater()) {
    if (version == "6.1")
        return "6.1";
}

if (IsWindows8Point1OrGreater())
    return "6.3";
else
    return "10.0";
}

【讨论】:

  • vc140 编译器发出错误并说 GetVersionEx 已弃用
【解决方案4】:

没错,检测这是否是 Windows 10 的唯一方法是使用

BOOL WINAPI IsWindows10OrGreater(void);

虽然您需要使用 Visual Studio 2015 拥有最新的 SDK。 请注意,

BOOL WINAPI IsWindowsVersionOrGreater(
WORD wMajorVersion,
WORD wMinorVersion,
WORD wServicePackMajor);

不适用于 Windows 10,同样:

BOOL WINAPI GetVersionEx( _Inout_ LPOSVERSIONINFO lpVersionInfo);

有时会返回 6.2 或 6.3。 (在 Windows 10 上完全弃用)。

【讨论】:

  • IsWindowsVersionOrGreater() 或 IsWindowsVersionOrGreater() 在 Win10 上也不适合我
猜你喜欢
  • 2016-02-17
  • 2021-10-07
  • 1970-01-01
  • 1970-01-01
  • 2016-03-22
  • 1970-01-01
  • 1970-01-01
  • 2016-10-20
  • 2020-07-30
相关资源
最近更新 更多