C++ 如何以编程方式获取 DLL 或 EXE 文件的版本?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/940707/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 18:04:32  来源:igfitidea点击:

How do I programmatically get the version of a DLL or EXE file?

c++winapidllversionexe

提问by JSB????

I need to get the product version and file version for a DLL or EXE file using Win32 native APIs in C or C++. I'm notlooking for the Windows version, but the version numbers that you see by right-clicking on a DLL file, selecting "Properties", then looking at the "Details" tab. This is usually a four-part dotted version number x.x.x.x.

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

回答by crashmstr

You would use the GetFileVersionInfoAPI.

您将使用GetFileVersionInfoAPI。

See Using Version Informationon the MSDN site.

请参阅MSDN 站点上的使用版本信息

Sample:

样本:

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;
}

回答by Dave Chandler

All these solutions did not work properly (with my system). I found out that each of the four parts of the version number are saved as a 16-bit value.

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

The first two numbers are saved in the 32-bit DWORD dwFileVersionMS, and the second two in dwFileVersionLS. So I edited your code at the output section like this:

前两个数字保存在 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
        );

And it works perfectly. The output is formatted like on my system:

它完美地工作。输出的格式类似于我的系统:

major.minor.build.revision

主要.次要.build.revision

回答by JSB????

You get this information using the version information APIs. Here is a sample:

您可以使用版本信息 API获取此信息。这是一个示例:

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
        );
}

回答by Vasya

This code shows the file version numbers correctly.

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

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

回答by Steve J

Found these articles...sorry, but I don't have direct experience with how to do this using native APIs, so I deferred to an Internet search:

找到了这些文章……抱歉,我没有直接使用本机 API 执行此操作的经验,因此我推迟到 Internet 搜索:

Hope these help!

希望这些有帮助!

回答by Dani van der Meer

The easiest way is to use the GetFileVersionInfoExor GetFileVersionInfoAPI functions.

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

You can also do it from within your application resources as explained here.

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

回答by Amadeus Hein

Since none of the answers mention it... I found out that you have to make different calculations depending on if you're running on 32- or 64-bit systems. That's why you find that certain answers in this question work for you, and others do not.

由于没有一个答案提到它......我发现你必须根据你是在 32 位系统还是 64 位系统上运行而进行不同的计算。这就是为什么您会发现这个问题中的某些答案适合您,而其他答案则不适合。

Here's a sample implementation I use:

这是我使用的示例实现:

if(IsWow64())
{
        // 64 bit build
        major =     (verInfo->dwProductVersionMS >> 16) & 0xffff;
        minor =     (verInfo->dwProductVersionMS >>  0) & 0xffff;
        revision =  (verInfo->dwProductVersionLS >> 16) & 0xffff;
        build =     (verInfo->dwProductVersionLS >>  0) & 0xffff;
} 
else
{
        // 32 bit build
        major =     HIWORD(verInfo->dwProductVersionMS);
        minor =     LOWORD(verInfo->dwProductVersionMS);
        revision =  HIWORD(verInfo->dwProductVersionLS);
        build =     LOWORD(verInfo->dwProductVersionLS);
}

And the implementation of IsWow64 (not mine):

以及 IsWow64 的实现(不是我的):

typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
LPFN_ISWOW64PROCESS fnIsWow64Process;

BOOL IsWow64()
{
    BOOL bIsWow64 = FALSE;

    //IsWow64Process is not available on all supported versions of Windows.
    //Use GetModuleHandle to get a handle to the DLL that contains the function
    //and GetProcAddress to get a pointer to the function if available.

    fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(
        GetModuleHandle(TEXT("kernel32")),"IsWow64Process");

    if(NULL != fnIsWow64Process)
    {
        if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64))
        {
            // Handle error...
        }
    }
    return bIsWow64;
}