?
Solved

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

Posted on 2007-07-19
10
Medium Priority
?
238 Views
Last Modified: 2010-04-05
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
0
Comment
Question by:John Fistere
  • 5
  • 2
  • 2
  • +1
10 Comments
 
LVL 19

Expert Comment

by:MerijnB
ID: 19529620
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
0
 
LVL 14

Expert Comment

by:Pierre Cornelius
ID: 19530952
It is the same in D7
0
 
LVL 2

Author Comment

by:John Fistere
ID: 19533179
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
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 4

Expert Comment

by:spk2000ar
ID: 19533226
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!!
0
 
LVL 2

Author Comment

by:John Fistere
ID: 19533792
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
0
 
LVL 4

Expert Comment

by:spk2000ar
ID: 19534693
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.

0
 
LVL 2

Author Comment

by:John Fistere
ID: 19536470
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
0
 
LVL 2

Author Comment

by:John Fistere
ID: 19536479
Also, I rebuilt MultiGraph and the Build Number stayed at 5926.

John
0
 
LVL 19

Accepted Solution

by:
MerijnB earned 1000 total points
ID: 19537366
A copy of my version information unit which works here.
To get what you want just call GetVersionInfo();



unit VersionInfo;

interface

uses SysUtils,
     Windows;

type PVersionInfo = ^TVersionInfo;
     TVersionInfo = record
      dwSignature       : DWORD;
      dwStrucVersion    : DWORD;
      wFileVersionMS    : WORD;  // Minor Version
      wFileVersionLS    : WORD;  // Major Version
      wProductVersionMS : WORD;  // Build Number
      wProductVersionLS : WORD;  // Release Version
      dwFileFlagsMask   : DWORD;
      dwFileFlags       : DWORD;
      dwFileOS          : DWORD;
      dwFileType        : DWORD;
      dwFileSubtype     : DWORD;
      dwFileDateMS      : DWORD;
      dwFileDateLS      : DWORD;
     end;

  procedure SetVersionFileName(FileName: String);

  function GetVersionInfo(FileName: String = ''): TVersionInfo;

  function GetVersionString(FileName: string = ''): String;
  function GetSmallVersionString(FileName: string = ''): String;
  function GetMajor(FileName: string = ''): String;
  function GetMinor(FileName: string = ''): String;
  function GetRelease(FileName: string = ''): String;
  function GetBuild(FileName: string = ''): String;

  function IsNewerVersion(OldVersionString, NewVersionString: string): boolean;

  var VerFileName: String;

implementation

uses Classes;

procedure FixDir(var DirName: String);
begin
 if Length(DirName) > 0 then
  if DirName[Length(DirName)] <> '\' then
   DirName := DirName + '\';
end;

function GetVersionString(FileName: string = ''): String;
// returns a complete version string (major.minor.release.build)
//
var VersionInfo: TVersionInfo;
begin
 if FileName = '' then
  FileName := ParamStr(0);

 VersionInfo := GetVersionInfo(FileName);
 Result := IntToStr(VersionInfo.wFileVersionLS) + '.' +     // major version
           IntToStr(VersionInfo.wFileVersionMS) + '.' +     // minor version
           IntToStr(VersionInfo.wProductVersionLS) + '.' +  // release
           IntToStr(VersionInfo.wProductVersionMS);         // build
end;

function GetSmallVersionString(FileName: string = ''): String;
// returns a small version string (major.minor 'build' build)
//
begin
 Result := GetMajor(FileName) + '.' + GetMinor(FileName) + ' build ' + GetBuild(FileName);
end;

function GetMajor(FileName: string = ''): String;
// returns string with major version
//
var VersionInfo: TVersionInfo;
begin
 if VerFileName = '' then
  FileName := ParamStr(0);

 VersionInfo := GetVersionInfo(FileName);
 Result := IntToStr(VersionInfo.wFileVersionLS);
end;

function GetMinor(FileName: string = ''): String;
// returns string with minor version
//
var VersionInfo: TVersionInfo;
begin
 if VerFileName = '' then
  FileName := ParamStr(0);

 VersionInfo := GetVersionInfo(FileName);
 Result := IntToStr(VersionInfo.wFileVersionMS);
end;

function GetRelease(FileName: string = ''): String;
// returns string with release number
//
var VersionInfo: TVersionInfo;
begin
 if VerFileName = '' then
  FileName := ParamStr(0);

 VersionInfo := GetVersionInfo(FileName);
 Result := IntToStr(VersionInfo.wProductVersionLS);
end;

function GetBuild(FileName: string = ''): String;
// returns string with build number
//
var VersionInfo: TVersionInfo;
begin
 if VerFileName = '' then
  FileName := ParamStr(0);

 VersionInfo := GetVersionInfo(FileName);
 Result := IntToStr(VersionInfo.wProductVersionMS);
end;

function GetVersionInfo(FileName: string = ''): TVersionInfo;
// returns a TVersionInfo record with all verion details (see declaration above)
//
var dwHandle, dwVersionSize: DWORD;
    strSubBlock            : String;
    pTemp                  : Pointer;
    pData                  : Pointer;
begin
 if FileName = '' then
  FileName := ParamStr(0);
 
 strSubBlock := '\';

 // get version information values
 dwVersionSize := GetFileVersionInfoSize(PChar(FileName), // pointer to filename string
                                         dwHandle);       // pointer to variable to receive zero

 if dwVersionSize <> 0 then                               // if GetFileVersionInfoSize is successful
 begin
  GetMem(pTemp, dwVersionSize);                           // allocate memory
  try
   if GetFileVersionInfo(PChar(FileName),                 // pointer to filename string
                         dwHandle,                        // ignored
                         dwVersionSize,                   // size of buffer
                         pTemp) then                      // pointer to buffer to receive file-version info.

    if VerQueryValue(pTemp,                               // pBlock     - address of buffer for version resource
                     PChar(strSubBlock),                  // lpSubBlock - address of value to retrieve
                     pData,                               // lplpBuffer - address of buffer for version pointer
                     dwVersionSize) then                  // puLen      - address of version-value length buffer
     Result := PVersionInfo(pData)^;
  finally
   FreeMem(pTemp);
  end; // try
 end // if dwVersionSize
 else
  with result do
  begin
   dwSignature       := 0;
   dwStrucVersion    := 0;
   wFileVersionMS    := 0;  // Minor Version
   wFileVersionLS    := 0;  // Major Version
   wProductVersionMS := 0;  // Build Number
   wProductVersionLS := 0;  // Release Version
   dwFileFlagsMask   := 0;
   dwFileFlags       := 0;
   dwFileOS          := 0;
   dwFileType        := 0;
   dwFileSubtype     := 0;
   dwFileDateMS      := 0;
   dwFileDateLS      := 0;
  end;
end;

procedure SetVersionFileName(FileName: String);
// set the filename for the version functions, of the filename is empty, ParamStr(0) will be used !
//
begin
 VerFileName := FileName;
end;


function IsNewerVersion(OldVersionString, NewVersionString: string): boolean;

 procedure ParseVersion(OldVersionString: string; out OldMajor, OldMinor, OldRelease, OldBuild: integer);
 begin
  with TStringList.Create() do
  begin
   Delimiter := '.';
   DelimitedText := OldVersionString;

   if Count < 4 then
   begin
    OldMajor := 0;
    OldMinor := 0;
    OldRelease := 0;
    OldBuild := 0;
   end
   else
   begin
    OldMajor := StrToIntDef(Strings[0], 0);
    OldMinor := StrToIntDef(Strings[1], 0);
    OldRelease := StrToIntDef(Strings[2], 0);
    OldBuild := StrToIntDef(Strings[3], 0);
   end;

   Free();
  end;
 end;

var OldMajor, OldMinor, OldRelease, OldBuild: integer;
    NewMajor, NewMinor, NewRelease, NewBuild: integer;
begin
 ParseVersion(OldVersionString, OldMajor, OldMinor, OldRelease, OldBuild);
 ParseVersion(NewVersionString, NewMajor, NewMinor, NewRelease, NewBuild);

 result := (((OldMajor < NewMajor)) or
            ((OldMajor <= NewMajor) and (OldMinor < NewMinor)) or
            ((OldMajor <= NewMajor) and (OldMinor <= NewMinor) and (OldRelease < NewRelease)) or
            ((OldMajor <= NewMajor) and (OldMinor <= NewMinor) and (OldRelease <= NewRelease) and (OldBuild < NewBuild)));
end;

end.
0
 
LVL 2

Author Comment

by:John Fistere
ID: 19539815
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
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Loops Section Overview
Despite its rising prevalence in the business world, "the cloud" is still misunderstood. Some companies still believe common misconceptions about lack of security in cloud solutions and many misuses of cloud storage options still occur every day. …
Suggested Courses

807 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question