使用 GetFileVersionInfo API (C++) 以编程方式获取 .exe 的 ProductVersion

Posted

技术标签:

【中文标题】使用 GetFileVersionInfo API (C++) 以编程方式获取 .exe 的 ProductVersion【英文标题】:Programmatically get the ProductVersion of .exe using GetFileVersionInfo API (C++) 【发布时间】:2018-01-12 06:19:40 【问题描述】:

引用此answer 我正在尝试使用GetFileVersionInfo 方法获取带有Windows Api 的ProductVersion。问题是通过 .exe ProductVersion 的属性是可见的,但通过编程我只得到“0.0.0.0”。

.exe 属性:

输出:

代码:

                printf( "File Version 1: %d.%d.%d.%d\n",
                    ( verInfo->dwFileVersionMS >> 16 ) & 0xffff,
                    ( verInfo->dwFileVersionMS >>  0 ) & 0xffff,
                    ( verInfo->dwFileVersionLS >> 16 ) & 0xffff,
                    ( verInfo->dwFileVersionLS >>  0 ) & 0xffff
                    );

                printf( "File Version 2: %d.%d.%d.%d\n",
                    ( verInfo->dwFileVersionLS >> 24 ) & 0xff,
                    ( verInfo->dwFileVersionLS >> 16 ) & 0xff,
                    ( verInfo->dwFileVersionLS >>  8 ) & 0xff,
                    ( verInfo->dwFileVersionLS >>  0 ) & 0xff
                    );


                printf( "Product Version 1: %d.%d.%d.%d\n",
                    ( verInfo->dwProductVersionLS >> 24 ) & 0xff,
                    ( verInfo->dwProductVersionLS >> 16 ) & 0xff,
                    ( verInfo->dwProductVersionLS >>  8 ) & 0xff,
                    ( verInfo->dwProductVersionLS >>  0 ) & 0xff
                    );

                printf( "Product Version 2: %d.%d.%d.%d\n",
                    (verInfo->dwProductVersionMS >> 16) & 0xffff,
                    (verInfo->dwProductVersionMS >>  0) & 0xffff,
                    (verInfo->dwProductVersionLS >> 16) & 0xffff,
                    (verInfo->dwProductVersionLS >>  0) & 0xffff
                    );

                printf( "Product Version 3: %d.%d.%d.%d\n",
                    (verInfo->dwProductVersionMS >> 16) & 0xffff,
                    (verInfo->dwProductVersionMS >>  8) & 0xffff,
                    (verInfo->dwProductVersionLS >> 16) & 0xffff,
                    (verInfo->dwProductVersionLS >>  8) & 0xffff
                    );

问题是 - WTF?如何获得 ProductVersion,微软的人是如何做到的?

【问题讨论】:

How do I read from a version resource in Visual C++ 的可能重复项。您正在寻找的是来自特定语言(或中性)StringFileInfoProductVersion 您在对话框中看到的只是字符串部分。但与更新或安装程序相关的是 VERSIONINFO 部分中的 DWORD 顺便说一句,您的代码中只有“文件版本 1”和“产品版本 2”是正确的。其他人使用不正确的换档。每个组件的版本号都是16位的,dwProductVersionMSdwProductVersionLS各存储两个组件。 【参考方案1】:

这对我有用

   fwprintf(f_output, L"// File Version:\t\t\t%d.%d.%d.%d\n",
        (verInfo->dwFileVersionMS >> 16) & 0xffff,
        (verInfo->dwFileVersionMS >> 0) & 0xffff,
        (verInfo->dwFileVersionLS >> 16) & 0xffff,
        (verInfo->dwFileVersionLS >> 0) & 0xffff
    );
    fwprintf(f_output, L"// Product Version:\t\t\t%d.%d.%d.%d\n",
        (verInfo->dwProductVersionMS >> 16) & 0xffff,
        (verInfo->dwProductVersionMS >> 0) & 0xffff,
        (verInfo->dwProductVersionLS >> 16) & 0xffff,
        (verInfo->dwProductVersionLS >> 0) & 0xffff
    );

【讨论】:

【参考方案2】:

这里是代码 sn-p 给那些也试图获得 ProductVersion 的人:

if (!VerQueryValue (lpData, TEXT("\\StringFileInfo\\040904E4\\ProductVersion"),
        (LPVOID) &lpBuffer, (PUINT) &BufLen)) 
    /* language ID 040904E4: U.S. English, char set = Windows, Multilingual */
    printf ("ProductVersion:       not found\n");

else
    printf ("ProductVersion:       %s\n", lpBuffer);

这里是Full Code。

【讨论】:

【参考方案3】:

版本信息资源包含一个小的固定部分 (VS_FIXEDFILEINFO) 和一些可选的字符串。

有些应用程序显示固定部分的数字,有些应用程序使用 FileVersion/ProductVersion 字符串。

如果字符串存在,您可能应该使用它,因为它允许开发人员添加额外的信息,如 Alpha/Beta 等,并且因为有些人忘记在固定部分正确设置正确的版本。

使用VerQueryValue 函数获取语言列表和字符串...

【讨论】:

如果字符串存在,您可能应该使用它 ...这取决于用例。如果您只想复制属性对话框显示的内容,请使用字符串版本。如果您需要比较两个文件的版本,则应始终使用固定信息,因为这是安装程序使用的。 @zett42 即使微软已经忘记更新固定版本号几次(在 WMP IIRC 中),字符串更有可能是正确的(但当然需要更多的工作来解析)。跨度> 一个好的应用程序应该显示版本资源中包含的全部信息(例如,Total Commander“文件信息”插件在这方面做得很好)。但是关于安装程序,您应该只依赖固定文件信息。如果文件的开发人员做错了,安装程序的工作不是猜测“真实”文件版本是什么。 @Anders,是的,我会将您的答案标记为正确的,谢谢您的提示。不知道还有多余的字符串。在那里我找到了 ProductVersion ,这真的很奇怪 VS_FIXEDFILEINFO 不包含这么大的产品的信息.. 微软的属性对话框用什么方式显示产品版本?来自资源字符串还是来自固定部分?

以上是关于使用 GetFileVersionInfo API (C++) 以编程方式获取 .exe 的 ProductVersion的主要内容,如果未能解决你的问题,请参考以下文章

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

您应该为 Windows API 调用 VerQueryValue 提供哪些参数

API 到 API - 使用服务帐户

使用REST API创建api需要哪些权限?

如果两个 API 使用不同的身份提供者,一个 API 将如何使用 oauth2 调用另一个 API?

Google Maps API 错误:此 API 密钥无权使用此服务或 API。地方 API 错误:ApiTargetBlockedMapError