Solved

Getting project version info

Posted on 1998-05-20
11
355 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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
 
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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Delphi Yen format 3 71
CheckListBox usage 3 96
Wincontrol not (correctly) drawn 15 57
Using MMsystem To change audio input 1 38
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…
Are you ready to implement Active Directory best practices without reading 300+ pages? You're in luck. In this webinar hosted by Skyport Systems, you gain insight into Microsoft's latest comprehensive guide, with tips on the best and easiest way…

739 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