Link to home
Start Free TrialLog in
Avatar of John Fistere
John FistereFlag for United States of America

asked on

In Delph 2007, I would like to increment a version counter each time I build my application.

I am running Delphi 2007 for Win32 under Win XP SR-2 and have successfully converted my D5 application, except for VersInfo.  I use it to increment part of the version number for each build.  I don't really use the complete VersInfo system.  I can't get it to work under D2007, and the program writer has not responded to my email.

All I really need is an integer that increments each time I build my application, and not when I compile it.  
Does D2007 have that kind of feature, or can someone tell me how to produce the same function?

Thanks,
John Fistere
Avatar of MerijnB
MerijnB
Flag of Netherlands image

I don't have D2007, so this could be wrong.
But in BDS2006 it's at: project -> options -> version info (check both 'include version number in project' and 'auto-increment build number')

you might find it in the same place for D2007
It is the same in D7
Avatar of John Fistere

ASKER

Thanks.  I still need some more help.  What I've done so far is:

var
  FileVer: string;
  Ch: Char;
  Dummy: dword;
  Handle: cardinal;
  VersionSize: integer;
begin
:
:
  VersionSize := GetFileVersionInfoSize('MultiGraph.exe',Handle);
  ShowMessage('VersionSize = '+IntToStr(VersionSize));
  GetFileVersionInfo('MultiGraph.exe',Dummy,VersionSize,^FileVer);

I get at an error at ^FileVer.   I am really not experienced with pointers.  

The error is E2010 Incompatible types: 'Ponter' and 'Char'

I want to display the version in my application.

Thanks,
John Fistere
I use this unit to decode version info of program. The initialization section shows how to call the function. This unit, included in your app, gives you all useful data (for me) from the exe file in  InformacionDelSistema (translated as ApplicationInfo) structure.

unit uInformacionDelSistema;

interface

type TInformacionDelSistema = record
                                Nombre,
                                Version,
                                Cliente,
                                Comentarios: string;
                              end;

var  InformacionDelSistema: TInformacionDelSistema;

implementation

uses Windows, SysUtils, Forms;

function DecodeVersionInfo(pInfo : pointer): TInformacionDelSistema;
var
  pItem : pointer;
      itemLen : UInt;
      FixedFileInfo : PVSFixedFileInfo;
      VersionSection: string;
  TempStr : string;
  Resultado: TInformacionDelSistema;
begin
  Resultado.Nombre      := 'SISTEMA';
  Resultado.Version     := '1.0.0.0';
  Resultado.Cliente     := '';
  Resultado.Comentarios := '';
      if VerQueryValue(pInfo, '\', Pointer(FixedFileInfo), itemLen) then
    begin
      {File Version}
      TempStr := IntToStr(HIWORD(FixedFileInfo^.dwFileVersionMS)) + '.' +
                 IntToStr(LOWORD(FixedFileInfo^.dwFileVersionMS)) + '.' +
                 IntToStr(HIWORD(FixedFileInfo^.dwFileVersionLS)) + '.' +
                 IntToStr(LOWORD(FixedFileInfo^.dwFileVersionLS));
      { This will make it compatible with all other Version programs }
      { And fit into Microsoft's standard's }
      while ((Copy(TempStr, Length(TempStr), 1)='0') or
             (Copy(TempStr, Length(TempStr), 1)='.')) do
        TempStr := copy(TempStr, 1, length(TempStr)-1);
      if (Pos('.', TempStr)<=0) then
        TempStr := TempStr + '.0';
      {Product Version}
      TempStr := IntToStr(HIWORD(FixedFileInfo^.dwProductVersionMS)) + '.' +
                 IntToStr(LOWORD(FixedFileInfo^.dwProductVersionMS)) + '.' +
                 IntToStr(HIWORD(FixedFileInfo^.dwProductVersionLS)) + '.' +
                 IntToStr(LOWORD(FixedFileInfo^.dwProductVersionLS));
      Resultado.Version := TempStr;
      {CopyRight Strings}
      VersionSection := '\StringFileInfo\' + IntToHex($409, 4) + IntToHex(1252, 4) + '\';
      if VerQueryValue(pInfo, PChar(VersionSection + 'ProductName'), pItem, itemLen) then
        Resultado.Nombre := PChar(pItem);
      if VerQueryValue(pInfo, PChar(VersionSection + 'CompanyName'), pItem, itemLen) then
        Resultado.Cliente := PChar(pItem);
      if VerQueryValue(pInfo, PChar(VersionSection + 'Comments'), pItem, itemLen) then
        Resultado.Comentarios := PChar(pItem);
    end;
  Result := Resultado;
end;

procedure GetVersionInfo(FFileName: string);
var versionHandle, versionSize : DWord;
        pVersionInfo : pointer;
begin
      versionSize := GetFileVersionInfoSize(PChar(FFileName), versionHandle);
      if versionSize = 0 then
            exit;
      getMem(pVersionInfo, versionSize);
      try
            if GetFileVersionInfo(PChar(FFileName), versionHandle, versionSize, pVersionInfo) then
                  InformacionDelSistema := DecodeVersionInfo(pVersionInfo);
      finally
            freeMem(pVersionInfo, versionSize);
      end;
end;

initialization
  GetVersionInfo(Lowercase(ExpandFilename(Application.Exename)));

end.

Hope this help!!
I got some more info, and here is how I have modified the code:

var
  FileVer: PAnsiChar;
  InfoHandle: cardinal;
  VersionInfoSize: dword;
  ptrVersionInfo: pointer;
  ptrInfo: pointer;
begin
  :
  :
  VersionInfoSize := GetFileVersionInfoSize('MultiGraph.exe',InfoHandle);
  GetMem(ptrVersionInfo,VersionInfoSize);
  ShowMessage('VersionInfoSize = '+IntToStr(VersionInfoSize));
  GetFileVersionInfo('MultiGraph.exe',InfoHandle,VersionInfoSize,ptrVersionInfo);
  VerQueryValue(ptrVersionInfo,FileVer,ptrInfo,VersionInfoSize);
  ShowMessage('FileVer = '+FileVer);

It compiles and runs but I get garbage for FileVer in the last statement.  The basic problem is that I don't understand the basics of what is going on.

John Fistere
replace ShowMessage line with

FileVerStr := IntToStr(HIWORD(PVSFixedFileInfo(ptrInfo)^.dwProductVersionMS)) + '.' +
                     IntToStr(LOWORD(PVSFixedFileInfo(ptrInfo)^.dwProductVersionMS)) + '.' +
                     IntToStr(HIWORD(PVSFixedFileInfo(ptrInfo)^.dwProductVersionLS)) + '.' +
                     IntToStr(LOWORD(PVSFixedFileInfo(ptrInfo)^.dwProductVersionLS));
ShowMessage(´FileVer = ´ + FileVerStr);

FileVerStr is just string type.

spk,
When I make your suggested modification I get the result:

FileVerStr = 191.2080.191.5926.

In the IDE, I followed earlier instructions:  Project / Options / Version Info, and set FileVersion to 6.0.0.7.  It is this string I expected to see.

Thanks, but something is not connecting.

John
Also, I rebuilt MultiGraph and the Build Number stayed at 5926.

John
ASKER CERTIFIED SOLUTION
Avatar of MerijnB
MerijnB
Flag of Netherlands image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Well, I finally realized that I was going to have to add a unit.  Since spk2000ar proposed the first unit, I tried it first.  I thought it would be good to add a little international flavor to my application.  However, i couldn't make it work, and it seemed that the reason might be stuff missing from the interface section.  Or that I did not know how to use what was there.

So I tried MerijnB's unit and it worked just fine.  All I wanted was the Major version and the Build, and I was able to get those directly.

Thanks to all who helped!

John