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

时间:2012-09-13 11:30:42

标签: c++ windows winapi versioning

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

实际上,我想要做的是能够在运行时显示“Version X.Y.Z”,而不必在某个地方使用我必须与我的ProductVersion和FileVersion保持同步。

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

4 个答案:

答案 0 :(得分:7)

如果操作系统是Windows,请使用GetFileVersionInfoVerQueryValue功能。

答案 1 :(得分:5)

我不相信有更简单的方法(比打开文件并使用GetFileVersionInfo和VerQueryValue)。我使用以下代码,以防它有用:

static CString GetProductVersion()
{
    CString strResult;

    char szModPath[ MAX_PATH ];
    szModPath[ 0 ] = '\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;
}

大卫

答案 2 :(得分:3)

唯一官方支持的方法是使用GetFileVersionInfo()VerQueryValue()。但是,正如您所注意到的,GetFileVersionInfo()要求您传入可执行文件的文件名。 There is a reason for this。尽管使用GetModuleFileName()获取正在运行的进程的文件名很简单,但它不是最有效的选项,特别是如果可执行文件是从远程共享运行的,并且如果可执行文件已经被保存,则甚至不能保证它是准确的。在进程开始运行后在HDD上进行了修改。

您可以通过调用FindResource()来查找进程的RT_VERSION资源,然后使用LoadResource()LockResource()来访问已在内存中运行的进程的版本信息获取指向其数据的指针。然后很有可能将该指针作为pBlock的{​​{1}}参数传递,但要注意这样做can crash your code!如果您直接访问VerQueryValue()资源,那么最好不要使用RT_VERSION。记录format of the RT_VERSION resource,因此您可以手动解析原始数据,这不是很困难。

答案 3 :(得分:1)

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

您可以找到here一个很好的工作示例(无ATL)。