You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在运行时通过ISO C代码获取Win32 UCRT版本?

如何在运行时通过ISO C代码获取UCRT版本?

要在运行时获取UCRT(Universal C Runtime)的版本,核心思路是读取UCRT核心库文件的版本信息——UCRT的版本与其对应的DLL文件版本完全一致。以下是基于ISO C标准编写的实现代码,无需依赖Windows特定的头文件:

实现代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 标准C兼容的Windows API声明(仅使用标准C类型)
extern void* LoadLibraryA(const char* lpLibFileName);
extern void* GetProcAddress(void* hModule, const char* lpProcName);
extern void* GetModuleHandleA(const char* lpModuleName);
extern unsigned long GetFileVersionInfoSizeA(const char* lptstrFilename, unsigned long* lpdwHandle);
extern int GetFileVersionInfoA(const char* lptstrFilename, unsigned long dwHandle, unsigned long dwLen, unsigned char* lpData);
extern int VerQueryValueA(const unsigned char* pBlock, const char* lpSubBlock, void** lplpBuffer, unsigned int* puLen);
extern unsigned long GetModuleFileNameA(void* hModule, char* lpFilename, unsigned long nSize);
extern void FreeLibrary(void* hModule);

// 存储文件版本信息的结构体(标准C兼容)
typedef struct {
    unsigned long dwSignature;
    unsigned long dwStrucVersion;
    unsigned long dwFileVersionMS;
    unsigned long dwFileVersionLS;
    unsigned long dwProductVersionMS;
    unsigned long dwProductVersionLS;
    unsigned long dwFileFlagsMask;
    unsigned long dwFileFlags;
    unsigned long dwFileOS;
    unsigned long dwFileType;
    unsigned long dwFileSubtype;
    unsigned long dwFileDateMS;
    unsigned long dwFileDateLS;
} VS_FIXEDFILEINFO;

#define MAX_PATH 260

int get_ucrt_version(unsigned int* major, unsigned int* minor, unsigned int* build, unsigned int* revision) {
    // 初始化输出参数
    if (major) *major = 0;
    if (minor) *minor = 0;
    if (build) *build = 0;
    if (revision) *revision = 0;

    // 获取UCRT核心模块句柄(优先Windows 10+的ucrtbase.dll,兼容旧系统的备用模块)
    void* ucrt_module = GetModuleHandleA("ucrtbase.dll");
    if (!ucrt_module) {
        ucrt_module = GetModuleHandleA("api-ms-win-crt-runtime-l1-1-0.dll");
        if (!ucrt_module) return -1;
    }

    // 获取模块文件路径
    char path[MAX_PATH];
    if (GetModuleFileNameA(ucrt_module, path, sizeof(path)) == 0) {
        return -2;
    }

    // 获取文件版本信息所需的内存大小
    unsigned long dummy;
    unsigned long version_size = GetFileVersionInfoSizeA(path, &dummy);
    if (version_size == 0) {
        return -3;
    }

    // 分配内存存储版本信息
    unsigned char* version_data = (unsigned char*)malloc(version_size);
    if (!version_data) {
        return -4;
    }

    // 读取文件版本信息
    if (!GetFileVersionInfoA(path, 0, version_size, version_data)) {
        free(version_data);
        return -5;
    }

    // 查询固定版本信息结构
    VS_FIXEDFILEINFO* fixed_info;
    unsigned int info_size;
    if (!VerQueryValueA(version_data, "\\", (void**)&fixed_info, &info_size)) {
        free(version_data);
        return -6;
    }

    // 拆分版本号:主版本、次版本、构建号、修订号
    if (major) *major = (fixed_info->dwFileVersionMS >> 16) & 0xFFFF;
    if (minor) *minor = fixed_info->dwFileVersionMS & 0xFFFF;
    if (build) *build = (fixed_info->dwFileVersionLS >> 16) & 0xFFFF;
    if (revision) *revision = fixed_info->dwFileVersionLS & 0xFFFF;

    // 清理资源
    free(version_data);
    return 0;
}

// 使用示例
int main() {
    unsigned int major, minor, build, revision;
    int result = get_ucrt_version(&major, &minor, &build, &revision);
    if (result == 0) {
        printf("UCRT Version: %u.%u.%u.%u\n", major, minor, build, revision);
        // 示例:检查版本是否低于存在缺陷的版本(如10.0.17134.0)
        if (major < 10 || 
            (major == 10 && minor < 0) || 
            (major == 10 && minor == 0 && build < 17134)) {
            printf("Warning: Some features may not work correctly with this UCRT version.\n");
        }
    } else {
        printf("Failed to retrieve UCRT version. Error code: %d\n", result);
    }
    return 0;
}

关键说明

  • ISO C兼容性:代码仅使用标准C语法和类型,通过extern声明Windows API,避免依赖非标准头文件或扩展。
  • UCRT模块适配:优先尝试ucrtbase.dll(Windows 10+的主UCRT库),若失败则兼容旧系统的api-ms-win-crt-runtime-l1-1-0.dll。
  • 版本号解读:UCRT版本采用主版本.次版本.构建号.修订号格式,例如10.0.22621.3527,需以DLL文件版本为准,而非Windows系统版本。
  • 错误处理:返回的错误码可用于定位问题(如模块未找到、路径获取失败等)。

内容的提问来源于stack exchange,提问作者Roland Mainz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 15:28:19