I know Git is in while SVN is out, but I'm still using SVN. To burn version information, build date + time, and svn number into the .exe I use a batch file that gets executed right after the compilation script. The batch file uses VerPatch.exe to burn the info into the .exe. Here is that batch file:
REM
REM ----------------------------------------------------------
REM svn number gets written into svn.txt
REM
f:\mp\svn info f:\mp10\ > f:\mp10\billing\prbill10\include\svn.ch
Type f:\mp10\billing\include\svn.ch | Find "Revision:" > f:\mp10\billing\prbill10\include\svn.txt
REM
REM ---------------------------------------------------
REM
REM Environmental var VERSION is set from svn.txt
REM
SET /P SVNVERSION=<\mp10\billing\prbill10\include\svn.txt
SET VERSION=10.0.%SVNVERSION:~10,4%
REM
sET FILEDESCR=/s desc "Mp Billing Module"
sET BUILDINFO=/s pb "Built by %USERNAME%"
sET COMPINFO=/s company "Structured Systems Corp." /s (c) "(c)all rights reserved -2013"
sET PRODINFO=/s product "PrBill10" /pv "%VERSION%" /sc "Built on %date% %time% from SVN %SVNVERSION%"
REM
REM
REM verPatch burns these values into .exe
f:\mp10\verpatch-bin-1.0.9\verpatch f:\mp\Prbill10.exe /va %VERSION% %FILEDESCR% %COMPINFO% %PRODINFO% %BUILDINFO%
REM
REM
svn.exe gets installed when you install the svn client. Passing "info" as parameter to svn.exe will print a paragraph that includes de svn revision number. The second line that combines type with the vertical bar to pipe the output into the find command, will retrieve only the line with the revision number and that gets written into svn.txt. I now use the contents in svn.txt to set some variables. After setting the environmental variables, I use VerPatch.exe to burn the info into the .exe.
Because the batch file gets executed right after the compilation script, I always get up to date information on every .exe. To display the version information from the .exe at runtime I use code like this:
cExe := cFileName( GetModuleFileName( GetInstance() ) )
cText2 := cValToChar( GetFileVersionInfo( cExe, 1 ) )
....
#include <windows.h>
#include <hbapi.h>
HB_FUNC( GETFILEVERSIONINFO )
{
char * szFile = hb_parc( 1 );
UINT uAction = ISNUM( 2 ) ? hb_parni( 2 ) : 1;
DWORD dwHandle = 0;
DWORD dwSize = GetFileVersionInfoSize( szFile, &dwHandle );
char * szOut = NULL;
BOOL bOk = FALSE;
if( dwSize )
{
char * szBlock = ( char * ) hb_xgrab( 255 );
char * szSubBlock = ( char * ) hb_xgrab( 255 );
HGLOBAL hMem = GlobalAlloc( GMEM_MOVEABLE, dwSize );
VS_FIXEDFILEINFO * vsInfo;
UINT nLen = 0;
if( hMem )
{
LPVOID pMem = GlobalLock( hMem );
if( pMem && GetFileVersionInfo( szFile, dwHandle, dwSize, pMem ) )
{
if( VerQueryValue( pMem, "\\VarFileInfo\\Translation", ( LPVOID * ) &vsInfo, &nLen ) )
{
*( LPDWORD ) vsInfo = MAKELONG( HIWORD( *( LPDWORD ) vsInfo ), LOWORD( *( LPDWORD ) vsInfo ) );
sprintf( szBlock, "\\StringFileInfo\\%08lx\\", *( LPDWORD )( vsInfo ) );
switch( uAction )
{
case 1:
sprintf( szSubBlock, "%s%s", szBlock, "Comments" );
break;
case 2:
sprintf( szSubBlock, "%s%s", szBlock, "CompanyName" );
break;
case 3:
sprintf( szSubBlock, "%s%s", szBlock, "FileDescription" );
break;
case 4:
sprintf( szSubBlock, "%s%s", szBlock, "FileVersion" );
break;
case 5:
sprintf( szSubBlock, "%s%s", szBlock, "InternalName" );
break;
case 6:
sprintf( szSubBlock, "%s%s", szBlock, "LegalCopyright" );
break;
case 7:
sprintf( szSubBlock, "%s%s", szBlock, "LegalTrademarks" );
break;
case 8:
sprintf( szSubBlock, "%s%s", szBlock, "OriginalFilename" );
break;
case 9:
sprintf( szSubBlock, "%s%s", szBlock, "PrivateBuild" );
break;
case 10:
sprintf( szSubBlock, "%s%s", szBlock, "ProductName" );
break;
case 11:
sprintf( szSubBlock, "%s%s", szBlock, "ProductVersion" );
break;
case 12:
sprintf( szSubBlock, "%s%s", szBlock, "SpecialBuild" );
break;
}
if( VerQueryValue( pMem, szSubBlock, ( LPVOID * ) &szOut, &nLen ) )
bOk = TRUE;
hb_xfree( szBlock );
hb_xfree( szSubBlock );
}
GlobalUnlock( hMem );
GlobalFree( hMem );
}
}
}
if( bOk )
hb_retc( szOut );
else
hb_retc( "" );
}
#pragma ENDDUMP
Hope that helps.
Reinaldo.