为啥 Windows 10 中 kernel32.dll 上的 GetFileVersionInfo 返回版本 6.2?

Posted

技术标签:

【中文标题】为啥 Windows 10 中 kernel32.dll 上的 GetFileVersionInfo 返回版本 6.2?【英文标题】:Why does GetFileVersionInfo on kernel32.dll in Windows 10 return version 6.2?为什么 Windows 10 中 kernel32.dll 上的 GetFileVersionInfo 返回版本 6.2? 【发布时间】:2016-10-30 07:47:21 【问题描述】:

我正在尝试检索 kernel32.dll 版本以执行 Windows 版本检查。然而,由于某种原因,即使kernel32.dll 的版本(如文件属性中所示)是 10.0.10586.0,返回的版本是:6.2.10586.0 怎么来的?

    DWORD dwDummy;
    DWORD dwFVISize = GetFileVersionInfoSize(lpszFilePath, &dwDummy);
    LPBYTE lpVersionInfo = new BYTE[dwFVISize];
    if (GetFileVersionInfo(lpszFilePath, 0, dwFVISize, lpVersionInfo) == 0)
    
        return FALSE;
    

    UINT uLen;
    VS_FIXEDFILEINFO *lpFfi;
    BOOL bVer = VerQueryValue(lpVersionInfo, L"\\", (LPVOID *)&lpFfi, &uLen);

    if (!bVer || uLen == 0)
    
        return FALSE;
    
    DWORD dwFileVersionMS = lpFfi->dwFileVersionMS;
    DWORD dwFileVersionLS = lpFfi->dwFileVersionLS;
    delete[] lpVersionInfo;

    DWORD dwLeftMost = HIWORD(dwFileVersionMS);
    DWORD dwSecondLeft = LOWORD(dwFileVersionMS);
    DWORD dwSecondRight = HIWORD(dwFileVersionLS);
    DWORD dwRightMost = LOWORD(dwFileVersionLS);

Kernel32.dll 属性(与 SysWow64 相同):

【问题讨论】:

将您的应用程序构建为 64 位可执行文件,看看是否得到相同的结果。 请参阅how to detect windows 10 in c++ 了解替代方法。 @RbMm: RtlGetNtVersionNumbers 未记录在案。它不是公共编程接口的一部分,并且可能在操作系统的未来版本中不可用。为什么不推荐RtlGetVersion呢?至少这是记录在案的(即使未来的操作系统可能也不支持从用户模式调用内核模式例程)。 @RbMm:编程与统计无关。仅仅因为 API 在 内没有改变并不意味着它不会在 消失。更好的性能永远不是忽略已记录 API 的正当理由。如果您不关心正确性,那么提高性能非常容易(通过完全省略调用)。 如果VerQueryValue 失败,此代码将泄漏内存,因为在释放lpVersionInfo 之前提前返回。没什么大不了的,只是想指出这一点。 【参考方案1】:

您从该任务的版本信息中读取了错误的字段。而不是dwFileVersionMSdwFileVersionLS 使用dwProductVersionMSdwProductVersionLS

文件版本字段存在supportedOS 兼容性问题。也就是说,它们的值取决于您的应用程序清单中声明的​​supportedOS 级别。另一方面,产品版本字段不依赖于清单。

【讨论】:

即使文件版本与产品版本相同,是否相关?我现在正在尝试。 你的代码在我运行它时产生 6.2,但当你使用正确的字段时产生 10.0。 @RbMm 我根本不明白那个评论。你明白人们为什么要检查系统 DLL 的产品版本吗? 我认为也许您应该向提问者提出这个问题,而不是评论我的回答,毕竟这只是解决了被问到的问题。记得提到RtlGetNtVersionNumbers 是一个未记录的 API,在未来的版本中可能不存在。另请注意,提问者正在按照 MS 的建议进行操作:msdn.microsoft.com/en-us/library/windows/desktop/… 其中说:要获取操作系统的完整版本号,请在其中一个系统 DLL(例如 Kernel32.dll)上调用 GetFileVersionInfo 函数,然后调用 VerQueryValue 以获取 \\ StringFileInfo\\\\ProductVersion 文件版本信息的子块。 最后,我不认为这段代码真的会成为性能瓶颈。【参考方案2】:

未针对 Windows 8.1 或 Windows 10 显示的应用程序将返回 Windows 8 操作系统版本值 (6.2)。

这是来自 GetVersionEx 函数 MSDN 的描述。对于 GetFileVersionInfo 没有这样的说明,但实际上这样做是一样的。我在调试器下查看:

所以 dwFileVersionMS 中的 10.0 ( 0xA000) 可以固定为 6.2 或 6.3 但 dwProductVersionMS - 未更改 (0xA000 ~ 10.0) 认为需要修复 GetFileVersionInfo[Ex] 的 MSDN 文档 :)

【讨论】:

您使用的是哪个调试器?你也能写出你执行的步骤吗? @SahilSingh - 我自己的。

以上是关于为啥 Windows 10 中 kernel32.dll 上的 GetFileVersionInfo 返回版本 6.2?的主要内容,如果未能解决你的问题,请参考以下文章

为啥装电脑版的安卓系统会出现这个?无法定位程序输入点GetTickCount64于动态链接库KERNEL32.dll上

为啥 Git 命令在 Windows 10 上通过 Win32-OpenSSH 失败?

通过 NHunspell 在 Windows Phone 8.1 应用程序中缺少 kernel32.dll

Windows Kernel32.BatteryLifePercent = 255

如何在 Windows 10 IoT 中设置系统时间?

引用“kernel32”读写ini配置文件