我注意到GetVersionEx()
声明已被弃用.更糟糕的是,对于Windows 8.1(可能是未来版本),版本号受应用程序清单的限制.
我的目标是收集用户正在运行的操作系统上的分析,因此我可以适当地定位支持.我想要一个收集这些数据的面向未来的解决方案.更新清单不起作用,因为我只能更新已发布的Windows版本的清单,而不是更新版本.建议的替换API(版本助手函数)是无用的.
如何收集实际的Windows版本号?
澄清一下:通过"未来验证",我只是说我想要有一个相当不错的机会在下一个版本的Windows上工作.没有什么是确定的,但文档确实说GetVersionEx()
不起作用.
ta.*_*.is 17
MSDN有一个示例显示如何使用(对于您的方案无用)版本帮助程序函数,但在介绍中如下:
要获取操作系统的完整版本号,请在其中一个系统DLL(如Kernel32.dll)上调用GetFileVersionInfo函数,然后调用VerQueryValue以获取文件版本信息的\ StringFileInfo \\ ProductVersion子块.
截至目前,GetFileVersionInfo
nor VerQueryValue
函数均未被弃用.
这将从中提取产品版本kernel32.dll
并将其打印到控制台:
#pragma comment(lib, "version.lib")
static const wchar_t kernel32[] = L"\\kernel32.dll";
wchar_t *path = NULL;
void *ver = NULL, *block;
UINT n;
BOOL r;
DWORD versz, blocksz;
VS_FIXEDFILEINFO *vinfo;
path = malloc(sizeof(*path) * MAX_PATH);
if (!path)
abort();
n = GetSystemDirectory(path, MAX_PATH);
if (n >= MAX_PATH || n == 0 ||
n > MAX_PATH - sizeof(kernel32) / sizeof(*kernel32))
abort();
memcpy(path + n, kernel32, sizeof(kernel32));
versz = GetFileVersionInfoSize(path, NULL);
if (versz == 0)
abort();
ver = malloc(versz);
if (!ver)
abort();
r = GetFileVersionInfo(path, 0, versz, ver);
if (!r)
abort();
r = VerQueryValue(ver, L"\\", &block, &blocksz);
if (!r || blocksz < sizeof(VS_FIXEDFILEINFO))
abort();
vinfo = (VS_FIXEDFILEINFO *) block;
printf(
"Windows version: %d.%d.%d",
(int) HIWORD(vinfo->dwProductVersionMS),
(int) LOWORD(vinfo->dwProductVersionMS),
(int) HIWORD(vinfo->dwProductVersionLS));
free(path);
free(ver);
Run Code Online (Sandbox Code Playgroud)
哎呀,目前接受的答案过于复杂。以下是如何快速可靠地获取当前窗口的版本(带有内部版本号),而不需要清单和其他无意义的技巧。并且适用于 Windows 2000 及更新版本(即现有的每个 Windows 版本)。
简短回答:使用RtlGetVersion。
没有 Windows 驱动程序开发套件?然后它比包含标头和使用函数稍微简单一些。以下是使用和不使用 WDK 时的操作方法。
使用 WDK,包括:
// Required for RtlGetVersion()
#pragma comment(lib, "ntdll.lib")
#include <Ntddk.h>
Run Code Online (Sandbox Code Playgroud)
没有 WDK,包括:
// Required for RtlGetVersion()
#pragma comment(lib, "ntdll.lib")
// Define the function because we don't have the driver development
// kit headers. We could probably acquire them but it makes development
// onboarding a pain in the ass for new employees.
extern "C" {
typedef LONG NTSTATUS, *PNTSTATUS;
#define STATUS_SUCCESS (0x00000000)
// Windows 2000 and newer
NTSYSAPI NTSTATUS NTAPI RtlGetVersion(PRTL_OSVERSIONINFOEXW lpVersionInformation);
}
Run Code Online (Sandbox Code Playgroud)
现在,只需获取准确的版本详细信息:
RTL_OSVERSIONINFOEXW osVers;
osVers.dwOSVersionInfoSize = sizeof(osVers);
// fill the structure with version details
NTSTATUS status = RtlGetVersion(&osVers);
// this should always succeed
assert(status == STATUS_SUCCESS);
Run Code Online (Sandbox Code Playgroud)
该osVers
变量现在包含准确的主要版本号、次要版本号和内部版本号。无需读取文件版本,也无需在运行时动态加载库。
请在其他答案之上投票,以便可以在应用程序中使用这个正确的代码,而不是在 rube-goldberg 其他答案中使用。谢谢。