getversionex 已被弃用,windows 10 后返回固定 6.2;应改用 iswindowsversionorgreater 和 verifyversioninfo(需链接 version.lib、正确包含头文件),或直接调用 rtlgetversion 获取真实 build 号,并确保 manifest 包含对应 supportedos id。

GetVersionEx 已被弃用,别再用了
Windows 10 之后,GetVersionEx 返回的版本号会被系统强制“冻结”为 6.2(即 Windows 8),哪怕你实际运行在 Windows 11 上。微软明确标记该函数为 deprecated,链接时可能触发 LNK4049 警告,运行时也可能返回错误结果。硬要用,等于主动放弃兼容性。
用 VerifyVersionInfo + IsWindowsVersionOrGreater 更可靠
推荐组合:先用 IsWindowsVersionOrGreater 快速判断是否 ≥ 某个版本(比如 Windows 10 1903),需要精确版本号时再调用 VerifyVersionInfo 配合 OSVERSIONINFOEX。这两者都属于 VersionHelpers.h 提供的封装,底层走的是 RtlGetVersion,不受 Manifest 干扰,也不被商店应用沙箱限制。
使用前需确保:
- 项目启用 Unicode(
_UNICODE和UNICODE宏已定义) - 链接
Version.lib(VS 默认不自动加,需手动在链接器输入中添加) - 头文件顺序:先
#include <versionhelpers.h></versionhelpers.h>,再#include <windows.h></windows.h>(否则可能因宏冲突编译失败)
获取完整版本号(含 Build Number)的正确姿势
如果必须拿到 dwBuildNumber(例如区分 Win10 22H2 和 23H2),得绕过 GetVersionEx,直接调用 NT 内部 API RtlGetVersion —— 它是唯一能真实反映当前系统 Build 的公开接口,且无需 Manifest 声明。
立即学习“C++免费学习笔记(深入)”;
【极品模板】出品的一款功能强大、安全性高、调用简单、扩展灵活的响应式多语言企业网站管理系统。 产品主要功能如下: 01、支持多语言扩展(独立内容表,可一键复制中文版数据) 02、支持一键修改后台路径; 03、杜绝常见弱口令,内置多种参数过滤、有效防范常见XSS; 04、支持文件分片上传功能,实现大文件轻松上传; 05、支持一键获取微信公众号文章(保存文章的图片到本地服务器); 06、支持一键
示例代码片段:
OSVERSIONINFOW osvi = {0};
osvi.dwOSVersionInfoSize = sizeof(osvi);
NTSTATUS status = RtlGetVersion(&osvi); // 注意:返回 NTSTATUS,不是 BOOL
if (NT_SUCCESS(status)) {
wprintf(L"Major: %lu, Minor: %lu, Build: %lu\n",
osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber);
}注意点:
-
RtlGetVersion是未文档化但稳定导出的函数,存在于ntdll.dll中,从 Windows XP 到 Windows 11 全系支持 - 不能直接声明为外部函数,需用
GetProcAddress(GetModuleHandle(L"ntdll.dll"), "RtlGetVersion")动态获取 - 返回值是
NTSTATUS,不是 Windows 常见的BOOL或DWORD,要检查NT_SUCCESS()宏
Manifest 文件影响所有版本检测函数
即使你用了 RtlGetVersion,若程序 manifest 中声明了 supportedOS 但漏掉当前系统(比如只写了 Windows 8 和 10,没加 Windows 11),部分系统 API(包括某些 WMI 查询)可能降级行为或返回默认值。这不是版本检测本身的问题,而是 Windows 应用兼容层的“善意干预”。
建议 manifest 至少包含:
<supportedOS Id="{8e0f7a12-f818-4b7d-815a-54f7eef75763}" /> <!-- Win11 -->
<supportedOS Id="{1f6f3552-69c7-453b-a016-951096932e4d}" /> <!-- Win10 -->漏掉新版 OS ID,有时连 IsWindows11OrGreater() 都会返回 false —— 这个细节很多人调试半天才意识到。










