Solved

Getting project version info

Posted on 1998-05-20
11
348 Views
Last Modified: 2010-04-06
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!
0
Comment
Question by:Ronald112197
11 Comments
 
LVL 4

Expert Comment

by:itamar
ID: 1346984
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
0
 
LVL 2

Author Comment

by:Ronald112197
ID: 1346985
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!
0
 
LVL 3

Expert Comment

by:rickpet
ID: 1346986
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.

0
 
LVL 2

Author Comment

by:Ronald112197
ID: 1346987
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?)
0
 
LVL 3

Expert Comment

by:rickpet
ID: 1346988
Ronald...

Yes...I like your enhancements...

Thanks

Rick

0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 3

Expert Comment

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

Rick
0
 
LVL 3

Expert Comment

by:rickpet
ID: 1346990
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.
0
 
LVL 2

Author Comment

by:Ronald112197
ID: 1346991
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!
0
 
LVL 3

Accepted Solution

by:
rickpet earned 50 total points
ID: 1346992
Okay...here's your answer... =)

Rick
0
 
LVL 2

Author Comment

by:Ronald112197
ID: 1346993
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!
0
 
LVL 6

Expert Comment

by:House_of_Dexter
ID: 25616840
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
  (http://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.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

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…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
This is a video that shows how the OnPage alerts system integrates into ConnectWise, how a trigger is set, how a page is sent via the trigger, and how the SENT, DELIVERED, READ & REPLIED receipts get entered into the internal tab of the ConnectWise …

939 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

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now