Solved

Getting project version info

Posted on 1998-05-20
11
347 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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

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…
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…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

746 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

9 Experts available now in Live!

Get 1:1 Help Now