Link to home
Start Free TrialLog in
Avatar of Ronald112197
Ronald112197Flag for Germany

asked on

Getting project version info

Simple question: How can I access the project version info that is displayed under Project | Options | VersionInfo at run-time? I'd like to display that information in an about-box and don't feel like manually changing it in 5 places all the time. Besides, I did choose "auto-increment build number" and would like to display the build number in my program.

I won't take "can't be done" for an (acceptable) answer! I'd figure that out by myself!

Thanks a lot for your help!
Avatar of itamar
itamar

Hi Ronald,

there is a freeware component (source-code) included that does exactly what you want for Delphi 3. The location is:

http://sunsite.icm.edu.pl/delphi/ftp/d10free/sverinfo.zip

IHTH,
Itamar
Avatar of Ronald112197

ASKER

Sorry for the delay, I'm quite busy right now and didn't have time to try it...

This component is quite nice and might be helpful in the future. For now, all I am looking for is code that'll give me the version (major, minor), release and build and I don't want to include a component of 1200+ lines of code just to get these numbers! I don't want to have to install & register components for every little piece of code - I'd never again be able to compile my code on a different system...

Could you tell me which code I need to get the information I need? I kind of tracked it down in the component, but couldn't find the lines where it is actually read...

 Thanks a lot!
unit rpVersionInfo;  //version 1.21 4/30/98 written and tested with Delphi 3.
(*Written by Rick Peterson, this component is released to the public domain for
  any type of use, private or commercial.  Should you enhance the product
  please give me credit and send me a copy.  Also please report any bugs to me.
  Send all corespondence to rickpet@airmail.net.  Thanks to Dietrich Raisin
   for the international enhancements *)

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  TypInfo;

type
{$M+}
(* Have you seen the $M+ before???This tells delphi to publish RTTI info for
   enumerated types.  Basically allowing your enumerated types to act as
   strings with GetEnumName *)
  TVersionType=(vtCompanyName, vtFileDescription, vtFileVersion, vtInternalName,
                vtLegalCopyright,vtLegalTradeMark, vtOriginalFileName,
                vtProductName, vtProductVersion, vtComments);
{$M-}
  TrpVersionInfo = class(TComponent)
(* This component will allow you to get Version Info from your program at
   RunTime *)
  private
    FVersionInfo : Array [0 .. ord(high(TVersionType))] of string;
  protected
    function GetCompanyName: string;
    function GetFileDescription: string;
    function GetFileVersion: string;
    function GetInternalName: string;
    function GetLegalCopyright: string;
    function GetLegalTradeMark: string;
    function GetOriginalFileName: string;
    function GetProductName: string;
    function GetProductVersion: string;
    function GetComments: string;
    function GetVersionInfo(VersionType: TVersionType): string; virtual;
    procedure SetVersionInfo; virtual;
  public
    constructor Create(AOwner: TComponent); override;
  published
(* Label1.Caption := VersionInfo1.FileVersion;  Simple as that.
   NOTE:  ALL the properties are READONLY so you can not set them with the
   Object Inspector. *)
    property CompanyName: string read GetCompanyName;
    property FileDescription: string read GetFileDescription;
    property FileVersion: string read GetFileVersion;
    property InternalName: string read GetInternalName;
    property LegalCopyright: string read GetLegalCopyright;
    property LegalTradeMark: string read GetLegalTradeMark;
    property OriginalFileName: string read GetOriginalFileName;
    property ProductName: string read GetProductName;
    property ProductVersion: string read GetProductVersion;
    property Comments: string read GetComments;
  end;

procedure Register;

implementation

constructor TrpVersionInfo.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  SetVersionInfo;
end;

function TrpVersionInfo.GetCompanyName: string;
begin
  result := GetVersionInfo(vtCompanyName);
end;

function TrpVersionInfo.GetFileDescription: string;
begin
  result := GetVersionInfo(vtFileDescription);
end;

function TrpVersionInfo.GetFileVersion: string;
begin
  result := GetVersionInfo(vtFileVersion);
end;

function TrpVersionInfo.GetInternalName: string;
begin
  result := GetVersionInfo(vtInternalName);
end;

function TrpVersionInfo.GetLegalCopyright: string;
begin
  result := GetVersionInfo(vtLegalCopyright);
end;

function TrpVersionInfo.GetLegalTradeMark: string;
begin
  result := GetVersionInfo(vtLegalTradeMark);
end;

function TrpVersionInfo.GetOriginalFileName: string;
begin
  result := GetVersionInfo(vtOriginalFileName);
end;

function TrpVersionInfo.GetProductName: string;
begin
  result := GetVersionInfo(vtProductName);
end;

function TrpVersionInfo.GetProductVersion: string;
begin
  result := GetVersionInfo(vtProductVersion);
end;

function TrpVersionInfo.GetComments: string;
begin
  result := GetVersionInfo(vtComments);
end;

function TrpVersionInfo.GetVersionInfo(VersionType: TVersionType): string;
begin
  result := FVersionInfo[ord(VersionType)];
end;

procedure TrpVersionInfo.SetVersionInfo;
type
   PLongInt= ^LongInt;
var
  sAppName,sVersionType : string;
  iAppSize, iLenOfValue, i: integer;
  pcBuf,pcValue: PChar;
begin
  pcBuf := nil; pcValue :=  nil;
  sAppName := Application.ExeName;
  iAppSize:= GetFileVersionInfoSize(PChar(sAppName),iAppSize);
  if iAppSize > 0 then
  begin
    try
      pcBuf := AllocMem(iAppSize);
      GetFileVersionInfo(PChar(sAppName),0,iAppSize,pcBuf);
      for i := 0 to Ord(High(TVersionType)) do
      begin
        sVersionType := GetEnumName(TypeInfo(TVersionType),i);
        sVersionType := Copy(sVersionType,3,length(sVersionType));
        VerQueryValue(pcBuf,PChar('\VarFileInfo\Translation'),
              Pointer(pcValue),iLenOfValue);
        sVersionType:= IntToHex(LoWord(PLongInt(pcValue)^),4)+
                         IntToHex(HiWord(PLongInt(pcValue)^),4)+
                         '\'+sVersionType;
        if VerQueryValue(pcBuf,PChar('\StringFileInfo\'+
                              sVersionType), Pointer(pcValue),iLenOfValue) then
          FVersionInfo[i] := pcValue;
      end;
    finally
      FreeMem(pcBuf,iAppSize);
    end;
  end;
end;

procedure Register;
begin
  RegisterComponents('FreeWare', [TrpVersionInfo]);
end;

end.

Thanks a lot itamar, but the code rickpet posted is exactly what I was looking for... small, easy and efficient :-) (adds only 2K to the executable)
I guess the component you mentioned is more powerful, but it's huge and complicated...

rickpet: Thanks a lot, the code is quite nice :-)

You asked to be informed about enhancements... here's a little one --- it doesn't add functionality, but makes the code much more compact and - I think - more readable :-)

      type
      {$M+}
        TVersionType=(vtCompanyName, vtFileDescription, vtFileVersion, vtInternalName,
                      vtLegalCopyright,vtLegalTradeMark, vtOriginalFileName,
                      vtProductName, vtProductVersion, vtComments);
      {$M-}
        TrpVersionInfo = class(TComponent)
      (* This component will allow you to get Version Info from your program at RunTime *)
        private
          FVersionInfo : Array [0 .. ord(high(TVersionType))] of string;
        protected
          function GetVersionInfo(index:integer): string; virtual; //only ONE function needed! :-)
          procedure SetVersionInfo; virtual;
        public
          constructor Create(AOwner: TComponent); override;
        published
          property CompanyName: string index ord(vtCompanyName) read GetVersionInfo;
          property FileDescription: string index ord(vtFileDescription) read GetVersionInfo;
          property FileVersion: string index ord(vtFileVersion) read GetVersionInfo;
          property InternalName: string index ord(vtInternalName) read GetVersionInfo;
          property LegalCopyright: string index ord(vtLegalCopyright) read GetVersionInfo;
          property LegalTradeMark: string index ord(vtLegalTrademark) read GetVersionInfo;
          property OriginalFileName: string index ord(vtOriginalFileName) read GetVersionInfo;
          property ProductName: string index ord(vtProductName) read GetVersionInfo;
          property ProductVersion: string index ord(vtProductVersion) read GetVersionInfo;
          property Comments: string index ord(vtComments) read GetVersionInfo;
        end;

      procedure Register;

      implementation

      constructor TrpVersionInfo.Create(AOwner: TComponent);
      begin
        inherited Create(AOwner);
        SetVersionInfo;
      end;

      function TrpVersionInfo.GetVersionInfo(index:integer): string;
      begin
        result := FVersionInfo[index];
      end;

      procedure TrpVersionInfo.SetVersionInfo;
.....

      procedure Register;
      begin
        RegisterComponents('FreeWare', [TrpVersionInfo]);
      end;

      end.

The effect is exactly the same, but the indexed method makes more sense and eliminates some sources for bugs... Hope you like it :-)

P.S.: How do I know which information is available? (i.e. how did you find the identifiers? I guess it's in the help file, but which keyword?)
Ronald...

Yes...I like your enhancements...

Thanks

Rick

Okay...got the info from "Windows 95: A Developer's Guide" by Jeffrey Richter and Jonathan Locke: Chapter Nine Version Control.

Rick
unit rpVersionInfo;  //version 1.22 6/03/98 written and tested with Delphi 3.
(*Written by Rick Peterson, this component is released to the public domain for
  any type of use, private or commercial.  Should you enhance the product
  please give me credit and send me a copy.  Also please report any bugs to me.
  Send all corespondence to rickpet@airmail.net.  Thanks to Dietrich Raisin and
  Ronald for the enhancements *)

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  TypInfo;

type
{$M+}
(* Have you seen the $M+ before???This tells delphi to publish RTTI info for
   enumerated types.  Basically allowing your enumerated types to act as
   strings with GetEnumName *)
  TVersionType=(vtCompanyName, vtFileDescription, vtFileVersion, vtInternalName,
                vtLegalCopyright,vtLegalTradeMark, vtOriginalFileName,
                vtProductName, vtProductVersion, vtComments);
{$M-}
  TrpVersionInfo = class(TComponent)
(* This component will allow you to get Version Info from your program at
   RunTime *)
  private
    FVersionInfo : Array [0 .. ord(high(TVersionType))] of string;
  protected
    function GetVersionInfo(index:integer): string; virtual;
    procedure SetVersionInfo; virtual;
  public
    constructor Create(AOwner: TComponent); override;
  published
(* Label1.Caption := VersionInfo1.FileVersion;  Simple as that.
   NOTE:  ALL the properties are READONLY so you can not set them with the
   Object Inspector. *)
    property CompanyName: string index ord(vtCompanyName) read GetVersionInfo;
    property FileDescription: string index ord(vtFileDescription) read GetVersionInfo;
    property FileVersion: string index ord(vtFileVersion) read GetVersionInfo;
    property InternalName: string index ord(vtInternalName) read GetVersionInfo;
    property LegalCopyright: string index ord(vtLegalCopyright) read GetVersionInfo;
    property LegalTradeMark: string index ord(vtLegalTradeMark) read GetVersionInfo;
    property OriginalFileName: string index ord(vtOriginalFileName) read GetVersionInfo;
    property ProductName: string index ord(vtProductName) read GetVersionInfo;
    property ProductVersion: string index ord(vtProductVersion) read GetVersionInfo;
    property Comments: string index ord(vtComments) read GetVersionInfo;
  end;

procedure Register;

implementation

constructor TrpVersionInfo.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  SetVersionInfo;
end;

function TrpVersionInfo.GetVersionInfo(index: integer): string;
begin
  result := FVersionInfo[index];
end;

procedure TrpVersionInfo.SetVersionInfo;
type
   PLongInt= ^LongInt;
var
  sAppName,sVersionType : string;
  iAppSize, iLenOfValue, i: integer;
  pcBuf,pcValue: PChar;
begin
  pcBuf := nil; pcValue :=  nil;
  sAppName := Application.ExeName;
  iAppSize:= GetFileVersionInfoSize(PChar(sAppName),iAppSize);
  if iAppSize > 0 then
  begin
    try
      pcBuf := AllocMem(iAppSize);
      GetFileVersionInfo(PChar(sAppName),0,iAppSize,pcBuf);
      for i := 0 to Ord(High(TVersionType)) do
      begin
        sVersionType := GetEnumName(TypeInfo(TVersionType),i);
        sVersionType := Copy(sVersionType,3,length(sVersionType));
        VerQueryValue(pcBuf,PChar('\VarFileInfo\Translation'),
              Pointer(pcValue),iLenOfValue);
        sVersionType:= IntToHex(LoWord(PLongInt(pcValue)^),4)+
                         IntToHex(HiWord(PLongInt(pcValue)^),4)+
                         '\'+sVersionType;
        if VerQueryValue(pcBuf,PChar('\StringFileInfo\'+
                              sVersionType), Pointer(pcValue),iLenOfValue) then
          FVersionInfo[i] := pcValue;
      end;
    finally
      FreeMem(pcBuf,iAppSize);
    end;
  end;
end;

procedure Register;
begin
  RegisterComponents('FreeWare', [TrpVersionInfo]);
end;

end.
rickpet: Maybe I'll post another comment (have to try s.th. at home first), but in any case, you'll have to post an "answer" so I can give you a grade!

C U l8er!
ASKER CERTIFIED SOLUTION
Avatar of rickpet
rickpet

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
ok, I don't have time to try the thing I wanted to try...

whatever, maybe I'll post something later.
Grade assigned: A

Your answer has solved my problem so far! Thanks a lot!
unit rpVersionInfo;
 //version 1.23 3/5/2009 rewritten and tested with Delphi 2006.
 //the original version was written in 6/03/98 and tested with Delphi 3.
 //minor changes - changed varibles to cardinals and minor bug fix
(*Written by Rick Peterson, this component is released to the public domain for
  any type of use, private or commercial.  Should you enhance the product
  please give me credit and send me a copy.  Also please report any bugs to me.
  Send all corespondence to houseofdexter@gmail.com.

  Thanks to Dietrich Raisin and  Ronald for the enhancements
  (https://www.experts-exchange.com/M_29098.html)*)

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  TypInfo;

type
{$M+}
(* Have you seen the $M+ before???This tells delphi to publish RTTI info for
   enumerated types.  Basically allowing your enumerated types to act as
   strings with GetEnumName *)
  TVersionType=(vtCompanyName, vtFileDescription, vtFileVersion, vtInternalName,
                vtLegalCopyright,vtLegalTradeMark, vtOriginalFileName,
                vtProductName, vtProductVersion, vtComments);
{$M-}
  TrpVersionInfo = class(TComponent)
(* This component will allow you to get Version Info from your program at
   RunTime *)
  private
    FVersionInfo : Array [0 .. ord(high(TVersionType))] of string;
    FAppName: string;
    function GetAppName: string;
    procedure SetAppName(const Value: string);
  protected
    function GetVersionInfo(index:integer): string;
    procedure SetVersionInfo;
  public
    constructor Create(AOwner: TComponent); override;
//NOTE: ApplicationName does not have to be set if this is in an application
//If it's in a DLL or console you are required to set it.
    property ApplicationName: string read GetAppName write SetAppName;

  published    
    property CompanyName: string index ord(vtCompanyName) read GetVersionInfo;
    property FileDescription: string index ord(vtFileDescription) read GetVersionInfo;
    property FileVersion: string index ord(vtFileVersion) read GetVersionInfo;
    property InternalName: string index ord(vtInternalName) read GetVersionInfo;
    property LegalCopyright: string index ord(vtLegalCopyright) read GetVersionInfo;
    property LegalTradeMark: string index ord(vtLegalTradeMark) read GetVersionInfo;
    property OriginalFileName: string index ord(vtOriginalFileName) read GetVersionInfo;
    property ProductName: string index ord(vtProductName) read GetVersionInfo;
    property ProductVersion: string index ord(vtProductVersion) read GetVersionInfo;
    property Comments: string index ord(vtComments) read GetVersionInfo;

(* Label1.Caption := VersionInfo1.FileVersion;  Simple as that.
   NOTE:  Most of the properties are READONLY so you can not set them with the
   Object Inspector, but you can see the Version Info for Delphi ;) *)

  end;

procedure Register;

implementation

constructor TrpVersionInfo.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  SetVersionInfo;
end;

function TrpVersionInfo.GetAppName: string;
begin
  if FAppName = '' then
    if Assigned(Application) then begin
      FAppName := Application.ExeName;
    end;
  Result := FAppName;
end;

procedure TrpVersionInfo.SetAppName(const Value: string);
begin
  if Value <> FAppName then
    FAppName := Value;
{If you are using a DLL you probably want to set this otherwise ignore it and
it will be set for you...If you don't know the name check out
 GetModuleFileName(hModule, lpFileName, nSize)}
end;

function TrpVersionInfo.GetVersionInfo(index: integer): string;
begin
  result := FVersionInfo[index];
end;


procedure TrpVersionInfo.SetVersionInfo;
type
   PLongInt= ^LongInt;
var
  sAppName,sVersionType : string;
  i: integer;
  cLenOfValue, cAppSize: Cardinal;
  pcBuf,pcValue: PChar;
begin
  pcValue :=  nil;
  sAppName := ApplicationName;
  cAppSize:= GetFileVersionInfoSize(PChar(sAppName),cAppSize);
  if cAppSize > 0 then  begin
  //moved the AllocMem outside the Try/Finally block where it should be
    pcBuf := AllocMem(cAppSize);
    try
      GetFileVersionInfo(PChar(sAppName),0,cAppSize,pcBuf);
      for i := 0 to Ord(High(TVersionType)) do  begin
        sVersionType := GetEnumName(TypeInfo(TVersionType),i);
        sVersionType := Copy(sVersionType,3,length(sVersionType));
        VerQueryValue(pcBuf,PChar('\VarFileInfo\Translation'),
              Pointer(pcValue),cLenOfValue);
        sVersionType:= IntToHex(LoWord(PLongInt(pcValue)^),4)+
                         IntToHex(HiWord(PLongInt(pcValue)^),4)+
                         '\'+sVersionType;
        if VerQueryValue(pcBuf,PChar('\StringFileInfo\'+
                              sVersionType), Pointer(pcValue),cLenOfValue) then
          FVersionInfo[i] := pcValue;
      end;
    finally
      FreeMem(pcBuf,cAppSize);
    end;
  end;
end;

procedure Register;
begin
  RegisterComponents('FreeWare', [TrpVersionInfo]);
end;

end.