如何在运行时从 ISO C 代码获取 UCRT 版本?我需要 ucrt 版本(不是 Windows 版本)来警告用户某些功能无法与某些有问题的 ucrt 版本一起使用。
框架挑战:只需静态链接 UCRT。
或者,您可以结合
GetModuleHandle
、GetModuleFileName
和版本查询功能来查询已加载的UCRT模块的版本。
自包含的 C++ 示例代码,具有最少的错误检查:
#include <array>
#include <expected>
#include <print>
#include <string>
#include <vector>
#define UNICODE
#include <Windows.h>
#pragma comment(lib, "version.lib")
struct UCRTVersion
{
std::array<std::uint16_t, 4> FileVersion;
std::array<std::uint16_t, 4> ProductVersion;
};
std::expected<UCRTVersion, HRESULT> GetUCRTVersion()
{
#ifdef _DEBUG
static constexpr auto DllName = L"ucrtbased.dll";
#else
static constexpr auto DllName = L"ucrtbase.dll";
#endif
const HMODULE ucrt{GetModuleHandle(DllName)};
if (!ucrt)
return std::unexpected(HRESULT_FROM_WIN32(GetLastError()));
std::wstring path;
path.resize_and_overwrite(_MAX_PATH, [ucrt](wchar_t *ptr, const std::size_t size)
{
return GetModuleFileName(ucrt, ptr, size);
});
const DWORD versionInfoSize{GetFileVersionInfoSize(path.c_str(), nullptr)};
if (!versionInfoSize)
return std::unexpected(HRESULT_FROM_WIN32(GetLastError()));
std::vector<std::byte> versionInfo(versionInfoSize);
if (!GetFileVersionInfo(path.c_str(), 0, versionInfo.size(), versionInfo.data()))
return std::unexpected(HRESULT_FROM_WIN32(GetLastError()));
VS_FIXEDFILEINFO *fixedFileInfo;
if (!VerQueryValue(versionInfo.data(), L"\\", reinterpret_cast<void **>(&fixedFileInfo), nullptr))
return std::unexpected(HRESULT_FROM_WIN32(GetLastError()));
return UCRTVersion{
{HIWORD(fixedFileInfo->dwFileVersionMS), LOWORD(fixedFileInfo->dwFileVersionMS),
HIWORD(fixedFileInfo->dwFileVersionLS), LOWORD(fixedFileInfo->dwFileVersionLS)},
{HIWORD(fixedFileInfo->dwProductVersionMS), LOWORD(fixedFileInfo->dwProductVersionMS),
HIWORD(fixedFileInfo->dwProductVersionLS), LOWORD(fixedFileInfo->dwProductVersionLS)}
};
}
int main()
{
const auto version = GetUCRTVersion();
if (!version)
{
std::println("Failed to get UCRT version: {:8X}", version.error());
return 1;
}
std::println("UCRT version: File = {}.{}.{}.{}, Product = {}.{}.{}.{}",
version->FileVersion[0],
version->FileVersion[1],
version->FileVersion[2],
version->FileVersion[3],
version->ProductVersion[0],
version->ProductVersion[1],
version->ProductVersion[2],
version->ProductVersion[3]
);
return 0;
}
UCRT version: File = 10.0.22621.2428, Product = 10.0.22621.2428