正在从应用程序中获取应用程序版本

Getting application version from within application

本文关键字:应用程序 获取 版本      更新时间:2023-10-16

有没有一种简单的方法可以在运行时从资源文件中获取应用程序版本信息?

实际上,我想做的是能够在运行时显示"版本X.Y.Z",而不需要在某个地方有一个单独的变量,我必须与我的ProductVersion和FileVersion保持同步。

澄清一下:是的,这是一个标准的C++Windows项目。我知道GetFileVersionInfo方法,但必须从内存中的版本中打开二进制文件来查询版本信息似乎很愚蠢-我确信我在这里缺少了一些明显的东西:-)

如果操作系统是Windows,请使用GetFileVersionInfoVerQueryValue函数。

我认为没有比打开文件并使用GetFileVersionInfo和VerQueryValue更简单的方法了。我使用以下代码,以防有帮助:

static CString GetProductVersion()
{
    CString strResult;
    char szModPath[ MAX_PATH ];
    szModPath[ 0 ] = '';
    GetModuleFileName( NULL, szModPath, sizeof(szModPath) );
    DWORD dwHandle;
    DWORD dwSize = GetFileVersionInfoSize( szModPath, &dwHandle );
    if( dwSize > 0 )
    {
        BYTE* pbBuf = static_cast<BYTE*>( alloca( dwSize ) );
        if( GetFileVersionInfo( szModPath, dwHandle, dwSize, pbBuf ) )
        {
            UINT uiSize;
            BYTE* lpb;
            if( VerQueryValue( pbBuf,
                               "\VarFileInfo\Translation",
                               (void**)&lpb,
                               &uiSize ) )
            {
                WORD* lpw = (WORD*)lpb;
                CString strQuery;
                strQuery.Format( "\StringFileInfo\%04x%04x\ProductVersion", lpw[ 0 ], lpw[ 1 ] );
                if( VerQueryValue( pbBuf,
                                   const_cast<LPSTR>( (LPCSTR)strQuery ),
                                   (void**)&lpb,
                                   &uiSize ) && uiSize > 0 )
                {
                    strResult = (LPCSTR)lpb;
                }
            }
        }
    }
    return strResult;
}

David

唯一官方支持的方法是使用GetFileVersionInfo()VerQueryValue()。但是,正如您所注意到的,GetFileVersionInfo()要求您传入可执行文件的文件名。这是有原因的。尽管使用GetModuleFileName()获取正在运行的进程的文件名很简单,但它并不是最有效的选项,尤其是当可执行文件从远程共享运行时,而且如果在进程开始运行后在HDD上修改了可执行文件,则它甚至不能保证是准确的。

您可以访问内存中已经运行的进程的版本信息,方法是调用FindResource()来定位进程的RT_VERSION资源,然后使用LoadResource()LockResource()来获取指向其数据的指针。然后将该指针作为VerQueryValue()pBlock参数传递是很诱人的,但要小心,因为这样做可能会使代码崩溃!如果您直接访问RT_VERSION资源,那么最好不要使用VerQueryValue()RT_VERSION资源的格式是有文档记录的,因此您可以手动解析原始数据,这不是很困难。

如前所述,没有简单的方法。

你可以在这里找到一个很好的工作示例(ATL免费)。