Как я могу получить номер версии Windows EXE или DLL? - PullRequest
5 голосов
/ 03 марта 2009

Как получить во время выполнения информацию о версии, хранящуюся в Windows EXE / DLL? Эта информация устанавливается вручную с помощью файла ресурсов.

Ответы [ 4 ]

6 голосов
/ 03 марта 2009

Вот способ C ++ сделать это, используя стандартные функции Windows API:

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 является чисто образовательной - в реальной ситуации вы бы правильно очистили после выделения памяти и фактически использовали код ошибки!

2 голосов
/ 03 марта 2009

Вот версия 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;
2 голосов
/ 03 марта 2009

Валентин отвечает правильно, но обратите внимание на предупреждение комментатора о возможности утечки памяти.

Я также не уверен, почему вы используете :: HeapAlloc в наши дни.

Вот фрагмент, который использует new и boost :: shared_array, чтобы сделать то же самое, что IMHO - более безопасный и чистый способ.

#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.... 
1 голос
/ 07 января 2010

Чтобы проверить сборки .NET, в C #:

System.Reflection.Assembly.LoadFile.. (@ "C: \ Windows \ Microsoft.NET \ Framework \ v2.0.50727 \ System.Data.dll") GetName () Version.ToString ();

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...