【问题标题】:Getting OS build version from Win32 Api C++从 Win32 Api C++ 获取操作系统构建版本
【发布时间】:2018-05-14 20:04:12
【问题描述】:

我正在尝试查找 Windows Server 2016 机器的构建版本,例如 RS1 或 RS3。有一个 API 可以做到这一点 - GetVersionEx() - 但现在已弃用。

MSDN 说改用Version Helper Functions

我想要构建版本,例如:RS1 的 1607。

有没有 API 可以得到这个?

【问题讨论】:

标签: c++ windows winapi operating-system


【解决方案1】:

选项 0:(按 RbMm)使用驱动程序开发工具包中的 [RtlGetVersion]。

选项 1:[更新] 获取系统 DLL 的版本号,例如 kernel32.dll。 MSDN 曾经对这种做法赞不绝口,说:

要获取操作系统的完整版本号,请在其中一个系统 DLL(例如 Kernel32.dll)上调用 GetFileVersionInfo 函数,然后调用 VerQueryValue 以获取文件版本信息的 \StringFileInfo\\ProductVersion 子块。 [来自大约 2017 年 MSDN 的 Internet Archive snapshot]

看起来像这样:

// Quick hack without error checking.
#include <cassert>
#include <iomanip>
#include <iostream>
#include <vector>
#include <Windows.h>

int main() {
  const auto system = L"kernel32.dll";
  DWORD dummy;
  const auto cbInfo =
      ::GetFileVersionInfoSizeExW(FILE_VER_GET_NEUTRAL, system, &dummy);
  std::vector<char> buffer(cbInfo);
  ::GetFileVersionInfoExW(FILE_VER_GET_NEUTRAL, system, dummy,
                          buffer.size(), &buffer[0]);
  void *p = nullptr;
  UINT size = 0;
  ::VerQueryValueW(buffer.data(), L"\\", &p, &size);
  assert(size >= sizeof(VS_FIXEDFILEINFO));
  assert(p != nullptr);
  auto pFixed = static_cast<const VS_FIXEDFILEINFO *>(p);
  std::cout << HIWORD(pFixed->dwFileVersionMS) << '.'
            << LOWORD(pFixed->dwFileVersionMS) << '.'
            << HIWORD(pFixed->dwFileVersionLS) << '.'
            << LOWORD(pFixed->dwFileVersionLS) << '\n';

  return 0;
}

请注意,original MSDN link 现在重定向到未提及此方法的较新文档集。我想这意味着这不再是一种受支持的技术,而且,据推测,旧代码的所有兼容性黑客可能会阻止应用程序获得实际答案。

方案二:查询注册表,具体为:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion

具有CurrentMajorVersionNumberCurrentMinorVersionNumberCurrentBuildNumber 的值。

我找不到这些值的官方文档,因此这可能不是 MSDN 批准的或面向未来的。

选项 3:如果可用则使用 GetProductInfo,如果不可用则回退到 GetVersionInfo。

【讨论】:

  • 为什么不使用选项 0 - 致电 RtlGetVersion 或未记录的 RtlGetNtVersionNumbers。无论如何,这种方式比较简单快捷
  • @zett42 - 不,RtlGetVersion 直到总是返回真正的 windows 版本,而不是寻找清单
  • @RbMm 谁来填充 PEB(你可以弄乱 PE 文件来设置其中一些值)?无论如何,看代码是没有意义的,因为这些函数被 alayers.dll 钩住了。
  • " MSDN 祝福这种方法" 我在链接页面上没有看到任何讨论使用 kernel32.dll 的内部版本号作为“祝福”或其他方式的内容。也许之前已经讨论过,但在撰写本文时还没有。我遇到过 kernel32.dll 的内部版本号与 winver.exe 报告的不同的情况。
  • @CharlesOppermann:MSDN 链接现在被重定向到微软较新的文档集,而较新的版本没有它。我将使用 Wayback Machine 捕获的相关位更新答案。
猜你喜欢
  • 2011-02-22
  • 2011-02-15
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 2010-10-08
  • 1970-01-01
  • 1970-01-01
  • 2011-09-13
相关资源
最近更新 更多