12

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

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

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

4

4 回答 4

7

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

于 2012-09-13T11:38:20.287 回答
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;
}

大卫

于 2012-09-13T14:25:50.267 回答
4

唯一官方支持的方法是使用GetFileVersionInfo()and VerQueryValue()。但是,正如您所注意到的,它GetFileVersionInfo()要求您传入可执行文件的文件名。 这是有原因的。虽然使用 获取正在运行的进程的文件名很简单GetModuleFileName(),但这并不是最有效的选择,特别是如果可执行文件是从远程共享运行的,并且如果可执行文件在 HDD 上被修改后甚至不能保证准确该进程已开始运行。

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

于 2012-09-13T21:57:54.970 回答
1

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

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

于 2015-02-05T10:45:25.267 回答