如何在运行时检索存储在 Windows exe/dll 中的版本信息?此信息是使用资源文件手动设置的。
Valentin Galea
问问题
2281 次
4 回答
7
这是使用标准 Windows API 函数的 C++ 方法:
try
{
TCHAR szFileName[ MAX_PATH ];
if( !::GetModuleFileName( 0, szFileName, MAX_PATH ) )
throw __LINE__;
DWORD nParam;
DWORD nVersionSize = ::GetFileVersionInfoSize( szFileName, &nParam );
if( !nVersionSize )
throw __LINE__;
HANDLE hMem = ::GetProcessHeap();
if( !hMem )
throw __LINE__;
LPVOID lpVersionData = ::HeapAlloc( hMem, 0, nVersionSize );
if( !lpVersionData )
throw __LINE__;
if( !::GetFileVersionInfo( szFileName, 0, nVersionSize, lpVersionData ) )
throw __LINE__;
LPVOID pVersionInfo;
UINT nSize;
if( !::VerQueryValue( lpVersionData, _T("\\"), &pVersionInfo, &nSize ) )
throw __LINE__;
VS_FIXEDFILEINFO *pVSInfo = (VS_FIXEDFILEINFO *)pVersionInfo;
CString strVersion;
strVersion.Format( _T(" version %i.%i.%i.%i"),
pVSInfo->dwProductVersionMS >> 16,
pVSInfo->dwProductVersionMS & 0xFFFF,
pVSInfo->dwProductVersionLS >> 16,
pVSInfo->dwProductVersionLS & 0xFFFF
);
GetDlgItem( IDC_ABOUT_VERSION )->SetWindowText( strAppName + strVersion );
if( !HeapFree( hMem, 0, lpVersionData ) )
throw __LINE__;
}
catch( int err )
{
ASSERT( !err ); // always break on debug builds to inspect error codes and such
DWORD dwErr = ::GetLastError();
// handle memory cleanup...
}
请注意,catch部分纯粹是教育性的——在实际情况下,您将在内存分配后正确清理并实际使用错误代码!
于 2009-03-03T15:20:02.920 回答
2
Valentin 的回答是正确的,但请注意评论者 plinth 关于内存泄漏可能性的警告。
我也不确定你为什么在这个时代使用 ::HeapAlloc。
这是一个片段,它使用 new 和 boost::shared_array 来做同样的事情,恕我直言,这是一种更安全、更清洁的方式。
#include <boost/shared_array.hpp>
//.....
DWORD dwHandle;
DWORD dwFileVersionInfoSize = GetFileVersionInfoSize((LPTSTR)lpszFileName, &dwHandle);
if (!dwFileVersionInfoSize)
return FALSE;
// ensure our data will be deleted
boost::shared_array<BYTE> data(new BYTE[dwFileVersionInfoSize]);
LPVOID const lpData = data.get();
//party on with lpData....
于 2009-03-03T16:32:47.473 回答
2
这是一个 Delphi 7 版本:
uses Windows, SysUtils;
function GetEXEVersion(exename: string; const Fmt : string = '%d.%d.%d.%d'): string;
{
credit to martinstoeckli@gmx.ch
( http://martinstoeckli.ch/delphi/delphi.html#AppVersion )
}
var
iBufferSize, iDummy : dword;
pBuffer, pFileInfo : Pointer;
iVer : array[1..4] of word;
begin
Result := '';
iBufferSize := GetFileVersionInfoSize(PChar(exename), iDummy);
if iBufferSize > 0 then begin
GetMem(pBuffer, iBufferSize);
try
GetFileVersionInfo(PChar(exename), 0, iBufferSize, pBuffer);
VerQueryValue(pBuffer, '\', pFileInfo, iDummy);
iVer[1] := HiWord(PVSFixedFileInfo(pFileInfo)^.dwFileVersionMS);
iVer[2] := LoWord(PVSFixedFileInfo(pFileInfo)^.dwFileVersionMS);
iVer[3] := HiWord(PVSFixedFileInfo(pFileInfo)^.dwFileVersionLS);
iVer[4] := LoWord(PVSFixedFileInfo(pFileInfo)^.dwFileVersionLS);
finally FreeMem(pBuffer);
end;
Result := Format(Fmt, [iVer[1],iVer[2],iVer[3],iVer[4]] );
end;
end;
于 2009-03-03T19:41:06.333 回答
1
要检查 .NET 程序集,在 C# 中:
System.Reflection.Assembly.LoadFile(@"c:\windows\Microsoft.NET\Framework\v2.0.50727\system.data.dll").GetName().Version.ToString();
于 2010-01-07T03:23:53.193 回答