有没有获得在运行时从资源文件的应用程序的版本信息的简单方法?
有效的什么我想要做的是能有一个“版本XYZ”在运行时显示,而无需单独的变量的地方,我必须保持同步与我的ProductVersion和文件版本。
为了澄清:是的,这是一个标准的C ++ Windows项目。 我知道的GetFileVersionInfo方法,但它似乎愚蠢不得不从内存中的版本中打开二进制只是查询版本信息-我敢肯定,我失去了一些东西很明显这里:-)
有没有获得在运行时从资源文件的应用程序的版本信息的简单方法?
有效的什么我想要做的是能有一个“版本XYZ”在运行时显示,而无需单独的变量的地方,我必须保持同步与我的ProductVersion和文件版本。
为了澄清:是的,这是一个标准的C ++ Windows项目。 我知道的GetFileVersionInfo方法,但它似乎愚蠢不得不从内存中的版本中打开二进制只是查询版本信息-我敢肯定,我失去了一些东西很明显这里:-)
如果操作系统是Windows上,使用GetFileVersionInfo
和VerQueryValue
功能。
我不相信有一个更简单的方式(不是打开该文件,并使用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;
}
大卫
唯一正式支持的方法是使用GetFileVersionInfo()
和VerQueryValue()
然而,正如你已经注意到了, GetFileVersionInfo()
需要你在可执行文件的文件名通过。 还有一个原因 。 虽然是简单的获得使用正在运行的进程的文件名GetModuleFileName()
它是不是最有效的选择,特别是如果可执行文件从远程共享中运行,它甚至没有保证是正确的,如果可执行文件已被修改的处理后的硬盘已开始运行。
您可以访问已在内存中运行的进程的版本信息,通过调用FindResource()
来查找进程的RT_VERSION
资源,然后使用LoadResource()
和LockResource()
来获得一个指向它的数据。 这是很有诱惑力的,然后传递指针作为pBlock
的参数VerQueryValue()
但要注意becaue这样做可能会崩溃你的代码 ! 如果您在访问RT_VERSION
资源直接,那么你是关闭不使用更好的VerQueryValue()
在所有。 在该格式RT_VERSION
资源被记录在案,这样你就可以手动分析原始数据,是不是很困难的。
前面已经说了,没有简单的方法。
你可以找到这里一个伟大的工作示例(ATL免费)。