在 Windows 平台下,获取操作系统版本信息最标准、最推荐的方法是使用 Windows API (Application Programming Interface),这个 API 专门为此目的设计,并且能正确处理从 Windows XP 到最新 Windows 11 的各种版本。

(图片来源网络,侵删)
我们将重点介绍两种主要方法:
- 推荐方法 (现代 Windows 10/11): 使用
VerifyVersionInfoW函数,这是微软官方推荐的方式。 - 传统方法 (兼容性更好): 使用
GetVersionEx函数,虽然已部分废弃,但在旧系统上更简单直接。
使用 VerifyVersionInfoW (推荐)
这是获取操作系统版本信息的现代、正确的方法,它使用一个掩码来精确查询你关心的版本特性,而不是返回一个可能被误导的版本号。
关键函数和数据结构
-
OSVERSIONINFOEXW结构体:- 这是
OSVERSIONINFO的扩展版本,包含了更丰富的信息,如服务包号、产品类型等。 wServicePackMajor和wServicePackMinor: 主次服务包版本号。dwMajorVersion: 主版本号 (Windows 10 是 10)。dwMinorVersion: 次版本号 (Windows 10 的 21H2 更新是 0)。dwBuildNumber: 内部构建号 (19044)。dwPlatformId: 平台 ID (VER_PLATFORM_WIN32_NT表示 Windows NT 及以后系统)。
- 这是
-
VerifyVersionInfoW函数:
(图片来源网络,侵删)- 作用: 检查当前系统是否满足指定的版本条件。
- 优点: 可以精确查询,避免
GetVersion的“兼容性模式”问题。 - 参数:
lpVersionInformation: 指向OSVERSIONINFOEXW结构体的指针。dwType: 一个掩码,指定要检查哪些版本信息 (VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER)。dwlConditionMask: 一个条件掩码,定义了版本号的比较逻辑 (是否大于、等于某个版本)。
完整示例代码
这个示例将检查当前系统是否为 Windows 10 或更高版本。
#include <windows.h>
#include <stdio.h>
#include <tchar.h> // 为了 _tprintf
// 需要链接 Version.lib 库
// 在 Visual Studio 中,项目属性 -> 链接器 -> 输入 -> 附加依赖项 中添加 Version.lib
// 在 GCC/MinGW 中,使用 -lversion 参数
int main() {
OSVERSIONINFOEXW osvi = { 0 };
DWORDLONG dwlConditionMask = 0;
int op = VER_GREATER_EQUAL; // 定义比较操作符: 大于或等于
// 1. 初始化 OSVERSIONINFOEXW 结构体
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
osvi.dwMajorVersion = 10; // 我们想检查的版本号: Windows 10
osvi.dwMinorVersion = 0;
// 2. 设置比较条件掩码
// VER_SET_CONDITION 是一个宏,用于构建条件掩码
VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, op);
VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, op);
// 3. 调用 VerifyVersionInfoW
// 如果系统版本 >= Windows 10,则返回 TRUE
if (VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION, dwlConditionMask)) {
_tprintf(_T("当前系统是 Windows 10 或更高版本,\n"));
// 获取更详细的版本信息
OSVERSIONINFOEXW detailed_osvi = { 0 };
detailed_osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
GetVersionExW((OSVERSIONINFOW*)&detailed_osvi);
_tprintf(_T("主版本号: %d\n"), detailed_osvi.dwMajorVersion);
_tprintf(_T("次版本号: %d\n"), detailed_osvi.dwMinorVersion);
_tprintf(_T("构建号: %d\n"), detailed_osvi.dwBuildNumber);
_tprintf(_T("服务包: %d.%d\n"), detailed_osvi.wServicePackMajor, detailed_osvi.wServicePackMinor);
// 根据构建号判断具体是哪个 Windows 10/11 版本
if (detailed_osvi.dwMajorVersion == 10) {
if (detailed_osvi.dwBuildNumber >= 22000) {
_tprintf(_T("具体版本: Windows 11\n"));
} else {
_tprintf(_T("具体版本: Windows 10\n"));
}
}
} else {
// 如果失败,调用 GetLastError 获取错误码
DWORD dwError = GetLastError();
if (dwError == ERROR_OLD_WIN_VERSION) {
_tprintf(_T("当前系统是 Windows 10 以下的版本,\n"));
} else {
_tprintf(_T("调用 VerifyVersionInfo 失败,错误码: %d\n"), dwError);
}
}
return 0;
}
如何编译
- Visual Studio: 创建一个“控制台应用”项目,代码可以直接运行。
- GCC/MinGW (命令行):
gcc -o get_version get_version.c -lversion ./get_version
注意:
-lversion链接Version.lib库是必须的。
使用 GetVersionEx (传统方法)
这个方法在旧的代码中很常见,但已从 Windows 8.1 和 Windows Server 2012 R2 起被弃用,在 Windows 8.1 及更高版本上,它为了兼容旧应用程序而返回一个被“伪装”过的版本号(即 Windows 8 的版本号)。不推荐在新项目中使用,除非你需要兼容非常古老的系统(如 Windows XP)。
完整示例代码
#include <windows.h>
#include <stdio.h>
#pragma comment(lib, "version.lib") // 链接库
int main() {
OSVERSIONINFO osvi = { 0 };
// 1. 初始化结构体
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
// 2. 调用 GetVersionEx
if (GetVersionEx(&osvi)) {
printf("成功获取版本信息,\n");
printf("主版本号: %d\n", osvi.dwMajorVersion);
printf("次版本号: %d\n", osvi.dwMinorVersion);
printf("构建号: %d\n", osvi.dwBuildNumber);
printf("平台 ID: %d\n", osvi.dwPlatformId);
printf("版本字符串: %s\n", osvi.szCSDVersion); // "Service Pack 3"
// 简单判断
if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
printf("当前系统是 Windows NT 内核系统,\n");
if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 1) {
printf("具体版本: Windows 7\n");
} else if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 2) {
printf("具体版本: Windows 8\n"); // 在 Win10/11 上这里也会显示 Win8
} else if (osvi.dwMajorVersion == 10) {
// 在 Win10/11 上,这里的主版本号会是 10,但次版本号会是 0
printf("主版本号是 10,但可能是 Windows 10/11 (GetVersionEx 不可靠),\n");
}
} else {
printf("当前系统可能是 Windows 95/98/Me,\n");
}
} else {
printf("调用 GetVersionEx 失败,错误码: %d\n", GetLastError());
}
return 0;
}
总结与对比
| 特性 | VerifyVersionInfoW (推荐) |
GetVersionEx (传统) |
|---|---|---|
| 推荐度 | 高 | 低 (已弃用) |
| 可靠性 | 高,不受应用程序兼容性模式影响 | 低,在 Win8.1+ 上返回被伪装的版本号 |
| 灵活性 | 高,可以精确查询特定版本条件 | 低,只能获取完整信息,无法进行精确查询 |
| 适用系统 | Windows XP 及以后 | Windows XP 及以后 (但在新系统上信息不准) |
| 使用场景 | 新项目,需要准确判断系统版本以调用特定 API | 维护旧代码,或需要兼容 Windows XP 等非常古老的系统 |
跨平台考虑
如果你写的 C 代码需要在 Linux 或 macOS 上运行,那么上述 Windows API 是无效的,你需要使用各自平台的系统调用:

(图片来源网络,侵删)
- Linux: 解析
/proc/version文件或使用uname系统调用。#include <sys/utsname.h> // ... struct utsname name; uname(&name); printf("OS: %s, Release: %s\n", name.sysname, name.release); - macOS: 同样使用
uname系统调用,或者通过读取系统文件(如/System/Library/CoreServices/SystemVersion.plist)来获取更详细的 macOS 版本。
在 Windows 平台下进行 C 语言编程时,若需获取操作系统版本信息,请务必使用 VerifyVersionInfoW 函数,这是微软官方推荐的最佳实践,能确保你的程序在各种 Windows 版本上都能正确、可靠地运行。
