2009-03-03 9 views

Répondre

6

Voici une C++ façon de le faire, en utilisant les fonctions API Windows standard:

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... 
} 

Notez que la prise partie est purement éducatif - dans une situation réelle, vous feriez bien le nettoyage après l'allocation de mémoire et utilise réellement le code d'erreur!

+0

S'il y a un lancement après votre appel à :: HeapAlloc, cela causera une fuite de mémoire. – plinth

2

La réponse de Valentin est correcte, mais notez l'avertissement de commenter plinth à propos de la possibilité d'une fuite de mémoire.

Je ne sais pas non plus pourquoi vous utiliseriez :: HeapAlloc de nos jours.

Voici un extrait qui utilise new et boost :: shared_array pour faire la même chose dans ce que IMHO est un moyen plus sûr et plus propre.

#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.... 
2

est ici une version Delphi 7:

uses Windows, SysUtils; 

function GetEXEVersion(exename: string; const Fmt : string = '%d.%d.%d.%d'): string; 
{ 
    credit to [email protected] 
    (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; 
1

Pour vérifier les assemblages .NET, en C#:

System.Reflection.Assembly.LoadFile (@ "c: \ windows \ Microsoft. NET \ Framework \ v2.0.50727 \ system.data.dll "). GetName(). Version.ToString();

Questions connexes