【问题标题】:How do I programmatically get the version of a DLL or EXE file?如何以编程方式获取 DLL 或 EXE 文件的版本?
【发布时间】:2010-10-30 18:06:54
【问题描述】:

我需要使用 C 或 C++ 中的 Win32 本机 API 获取 DLL 或 EXE 文件的产品版本和文件版本。我不是在寻找 Windows 版本,而是通过右键单击 DLL 文件,选择“属性”,然后查看“详细信息”选项卡所看到的版本号。这通常是一个四部分的虚线版本号 x.x.x.x。

【问题讨论】:

  • 您使用哪种语言?
  • 如果他只是想要 Win32 API 调用也没关系。任何支持调用系统 DLL 的语言都可以。
  • 编辑澄清这是关于 C/C++ 的。

标签: c++ winapi dll version exe


【解决方案1】:

您将使用GetFileVersionInfo API。

请参阅 MSDN 网站上的 Using Version Information

示例:

DWORD  verHandle = 0;
UINT   size      = 0;
LPBYTE lpBuffer  = NULL;
DWORD  verSize   = GetFileVersionInfoSize( szVersionFile, &verHandle);

if (verSize != NULL)
{
    LPSTR verData = new char[verSize];

    if (GetFileVersionInfo( szVersionFile, verHandle, verSize, verData))
    {
        if (VerQueryValue(verData,"\\",(VOID FAR* FAR*)&lpBuffer,&size))
        {
            if (size)
            {
                VS_FIXEDFILEINFO *verInfo = (VS_FIXEDFILEINFO *)lpBuffer;
                if (verInfo->dwSignature == 0xfeef04bd)
                {

                    // Doesn't matter if you are on 32 bit or 64 bit,
                    // DWORD is always 32 bits, so first two revision numbers
                    // come from dwFileVersionMS, last two come from dwFileVersionLS
                    TRACE( "File Version: %d.%d.%d.%d\n",
                    ( verInfo->dwFileVersionMS >> 16 ) & 0xffff,
                    ( verInfo->dwFileVersionMS >>  0 ) & 0xffff,
                    ( verInfo->dwFileVersionLS >> 16 ) & 0xffff,
                    ( verInfo->dwFileVersionLS >>  0 ) & 0xffff
                    );
                }
            }
        }
    }
    delete[] verData;
}

【讨论】:

  • int revision = HIWORD(verInfo->dwProductVersionLS); int build = LOWORD(verInfo->dwProductVersionLS);
  • 我知道这已经有一段时间了,但是对于像我这样的新手来说,这是获取 .exe 文件名的方式:TCHAR szVersionFile[MAX_PATH]; GetModuleFileName(NULL, szVersionFile, MAX_PATH );
  • @BurninatorDor 不要称自己为新手。到目前为止,我已经在 MFC 中编程了 6 年,这对我很有帮助。
  • 编辑了这个答案,因为它计算的版本号错误。来自 dwProductVersionMS 的 MSDN 文档:“文件二进制版本号的最高有效 32 位。此成员与 dwFileVersionLS 一起使用以形成用于数字比较的 64 位值。” ,因此您使用它们来计算版本号。前两个(主要/次要)在 versionMS 中,后两个(修订/构建)在 versionLS 中。 32/64位没关系,DWORD总是32位。
  • NULL 不应与DWORDs 一起使用(0 是正确的)
【解决方案2】:

所有这些解决方案都无法正常工作(使用我的系统)。我发现版本号的四个部分中的每一个都保存为一个 16 位的值。

前两个数字保存在 32 位 DWORD dwFileVersionMS 中,后两个数字保存在 dwFileVersionLS 中。所以我在输出部分编辑了你的代码,如下所示:

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

而且效果很好。输出的格式类似于我的系统:

major.minor.build.revision

【讨论】:

    【解决方案3】:

    您可以使用the version information APIs 获取此信息。这是一个示例:

    void PrintFileVersion( TCHAR *pszFilePath )
    {
        DWORD               dwSize              = 0;
        BYTE                *pbVersionInfo      = NULL;
        VS_FIXEDFILEINFO    *pFileInfo          = NULL;
        UINT                puLenFileInfo       = 0;
    
        // Get the version information for the file requested
        dwSize = GetFileVersionInfoSize( pszFilePath, NULL );
        if ( dwSize == 0 )
        {
            printf( "Error in GetFileVersionInfoSize: %d\n", GetLastError() );
            return;
        }
    
        pbVersionInfo = new BYTE[ dwSize ];
    
        if ( !GetFileVersionInfo( pszFilePath, 0, dwSize, pbVersionInfo ) )
        {
            printf( "Error in GetFileVersionInfo: %d\n", GetLastError() );
            delete[] pbVersionInfo;
            return;
        }
    
        if ( !VerQueryValue( pbVersionInfo, TEXT("\\"), (LPVOID*) &pFileInfo, &puLenFileInfo ) )
        {
            printf( "Error in VerQueryValue: %d\n", GetLastError() );
            delete[] pbVersionInfo;
            return;
        }
    
        // pFileInfo->dwFileVersionMS is usually zero. However, you should check
        // this if your version numbers seem to be wrong
    
        printf( "File Version: %d.%d.%d.%d\n",
            ( pFileInfo->dwFileVersionLS >> 24 ) & 0xff,
            ( pFileInfo->dwFileVersionLS >> 16 ) & 0xff,
            ( pFileInfo->dwFileVersionLS >>  8 ) & 0xff,
            ( pFileInfo->dwFileVersionLS >>  0 ) & 0xff
            );
    
        // pFileInfo->dwProductVersionMS is usually zero. However, you should check
        // this if your version numbers seem to be wrong.
    
        printf( "Product Version: %d.%d.%d.%d\n",
            ( pFileInfo->dwProductVersionLS >> 24 ) & 0xff,
            ( pFileInfo->dwProductVersionLS >> 16 ) & 0xff,
            ( pFileInfo->dwProductVersionLS >>  8 ) & 0xff,
            ( pFileInfo->dwProductVersionLS >>  0 ) & 0xff
            );
    }
    

    【讨论】:

    • 我认为这是错误的。对于文件版本 1.0.0.1,这个函数给了我“0.0.0.1”。我最终得到了@Vasya 的答案
    【解决方案4】:

    找到这些文章...抱歉,但我没有直接体验如何使用本机 API 执行此操作,因此我推迟到 Internet 搜索:

    希望这些帮助!

    【讨论】:

      【解决方案5】:

      此代码正确显示文件版本号。

      ( pFileInfo->dwFileVersionMS >> 16 ) & 0xff,
      ( pFileInfo->dwFileVersionMS >> 0 ) & 0xff,
      ( pFileInfo->dwFileVersionLS >>  16 ) & 0xff,
      ( pFileInfo->dwFileVersionLS >>  0 ) & 0xff);
      

      【讨论】:

      • 您能为这个答案提供一些背景信息吗?似乎不完整。如果它是对另一个答案的更正,请对其发表评论,或编辑该答案,它将被更有经验的用户批准。
      • 这肯定不会正常工作,如果版本包含任何大于 255 的组件,例如6.1.3709.2 四个分量是16位数字,不是8位。
      • 这是不正确的。版本的各个部分是 16 位值。代码应该是 ( pFileInfo->dwFileVersionMS >> 16 ) & 0xffff, ( pFileInfo->dwFileVersionMS >> 0 ) & 0xffff, ( pFileInfo->dwFileVersionLS >> 16 ) & 0xffff, ( pFileInfo->dwFileVersionLS >> 0 ) & 0xffff);
      • 就像很久以前一样!!!但我可以分享解决方案。然后我拒绝从内核驱动程序接收有关可执行文件的信息。然后我将此功能转移到服务中。驱动程序传输了有关进程启动的信息,并期望服务提供解决方案
      【解决方案6】:

      最简单的方法是使用GetFileVersionInfoExGetFileVersionInfo API 函数。

      您也可以按照here 的说明从应用程序资源中执行此操作。

      【讨论】:

        猜你喜欢
        • 2010-12-17
        • 1970-01-01
        • 2010-09-08
        • 2021-08-20
        • 2015-10-12
        • 1970-01-01
        • 1970-01-01
        • 2016-09-16
        相关资源
        最近更新 更多