Solved

How do I get the VersionInfo for my program from within my program?

Posted on 2001-07-02
13
423 Views
Last Modified: 2010-04-06
I want to show the fileversion number in my about box.

How do I get the FileVersion string that is defined within my project|Options|Version Info dialog?

Ideally, I don't want to have to re-open the application from disk.

I simply want to extract it from the current program.

Regards,

Richard Quadling.
0
Comment
Question by:Richard Quadling
  • 5
  • 2
  • 2
  • +3
13 Comments
 
LVL 13

Expert Comment

by:Epsylon
ID: 6245314
0
 
LVL 40

Author Comment

by:Richard Quadling
ID: 6245355
From this, can I surmise that the versioninfo is not available to the current program - I have to open the program twice to get the info?

Is it not held as a resource in the current application (I've been reading! Probably the wrong thing, but ... ;-) ).


Regards,

Richard Quadling.
0
 
LVL 2

Expert Comment

by:FrodoBeggins
ID: 6245459
You can use GetFileVersionInfo and VerQueryValue functions. Or use any kind of component - like TVersionInfo from the RX Components Suite
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 1

Expert Comment

by:bozo7
ID: 6245594
I use the following function

function GetProgramVersion(path : string) : string;
var
   nZero,nSize : cardinal;
   lpData      : pointer;
   p           : pointer;
begin
 result:='Unknown';
 nSize:=GetFileVersionInfoSize(pchar(path),nZero);
 if nSize>0 then
  begin
   getmem(lpData,nSize);
   if GetFileVersionInfo(pchar(path),0,nSize,lpData) then
    if VerQueryValue(lpData,'\',p,nZero) then
     begin
     result:=inttostr(tVSFIXEDFILEINFO(p^).dwFileVersionMS shr 16)+'.'+
             inttostr(tVSFIXEDFILEINFO(p^).dwFileVersionMS and $FFFF)+'.'+
             inttostr(tVSFIXEDFILEINFO(p^).dwFileVersionLS shr 16)+'.'+
             inttostr(tVSFIXEDFILEINFO(p^).dwFileVersionLS and $FFFF);
     end;
   freemem(lpData,nSize);
  end;
end;


Then I call it like this

version.caption := 'Release '+GetProgramVersion(application.exename);

I don't remember who gave me this function, but I got it on EE somehwhere. It works well though.

Ross
0
 
LVL 1

Expert Comment

by:bozo7
ID: 6245597
version.caption referenced above. Version is a TLabel.

Ross
0
 
LVL 2

Accepted Solution

by:
Felixin earned 50 total points
ID: 6247661
What about this unit ?

START
-----------------------------------------------------------
unit rpVersionInfo;
//version 1.0 3/8/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 coorespondence to rickpet@airmail.net. *)

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

var
  VersionInfo : TrpVersionInfo;

procedure Register;

implementation

const
  RootInfo = 'StringFileInfo\040A04E4\';

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;
var
  sAppName,sVersionType : string;
  iAppSize, iLenOfValue : DWord;
  i: integer;
  pcBuf,pcValue, Key: PChar;
begin
  sAppName := Application.ExeName;
  iAppSize:= GetFileVersionInfoSize(PChar(sAppName),iAppSize);
  if (iAppSize > 0) then
  begin
    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));
      Key := PChar (RootInfo + sVersionType);
      if VerQueryValue(pcBuf, Key, Pointer(pcValue),iLenOfValue) then
        FVersionInfo[i] := pcValue;
    end;
    FreeMem(pcBuf,iAppSize);
  end;
end;                            

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

initialization
  VersionInfo := TrpVersionInfo.Create (nil);

finalization
  VersionInfo.Free;

end.
-----------------------------------------------------------
END

I don't remember where I got the unit, but please note that I'm not the author.

The author is Rick Peterson.

I've been using this unit in Delphi 5 without problems.

Note also that you acces version information through the properties of te object like this

VersionInfo.ProductVersion;

Greetings

F?lix



0
 
LVL 40

Author Comment

by:Richard Quadling
ID: 6248270
Initially, I tried the unit above and got nowhere - the values where all blank.

I then tried to use the TResourceStream. Managed to get it loaded into some memory, but can't really work out how to navigate around it.

But I did manage to save it to disk!

Then noticed that there is a slightly different code at the top of the file which relates to the language Locale ID.

The example above uses a locale of $040A = Spanish (Traditional Sort).

I changed it to my language (English - United Kingdom $0809) and all works well.

Thanks.
0
 
LVL 40

Author Comment

by:Richard Quadling
ID: 6248274
Not EXACTLY what I wanted. I didn't want to have to reload the file, but it does what I want and doesn't seem too slow.

Thanks.

NOTE: More points but lower grade.
0
 
LVL 40

Author Comment

by:Richard Quadling
ID: 6248290
The new code (and my change is to the const RootInfo) is ...

------------------------------------------------
unit rpVersionInfo;
//version 1.0 3/8/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 coorespondence to rickpet@airmail.net. }

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

var
 VersionInfo : TrpVersionInfo;

procedure Register;

implementation

const
{
3rd July 2001 - Richard Quadling.
The Language Locale ID that is set in Project|Options relates to the first 4 characters after the first \ in the Root Info.

RootInfo = 'StringFileInfo\040A04E4\'; Spanish - Traditional Sort
}
      RootInfo = 'StringFileInfo\080904E4\'; { English - United Kingdom }

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;
var
 sAppName,sVersionType : string;
 iAppSize, iLenOfValue : DWord;
 i: integer;
 pcBuf,pcValue, Key: PChar;
begin
 sAppName := Application.ExeName;
 iAppSize:= GetFileVersionInfoSize(PChar(sAppName),iAppSize);
 if (iAppSize > 0) then
 begin
      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));
        Key := PChar (RootInfo + sVersionType);
        if VerQueryValue(pcBuf, Key, Pointer(pcValue),iLenOfValue) then
            FVersionInfo[i] := pcValue;
      end;
      FreeMem(pcBuf,iAppSize);
 end;
end;

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

initialization
 VersionInfo := TrpVersionInfo.Create (nil);

finalization
 VersionInfo.Free;

end.

0
 
LVL 2

Expert Comment

by:Felixin
ID: 6248627
Yes, in fact I have to pass a certain time to realize that the problem was in languaje code.

Sorry, for not mentioning it and thanks for the points.

Felixin
0
 

Expert Comment

by:dicktse
ID: 8277233
You don't need to hard-code the language ID. You can get the language ID by using this code:


procedure TrpVersionInfo.SeTVersionInfo;
var
  sAppName,sVersionType : string;
  iAppSize, iLenOfValue : DWord;
  i: integer;
  pcBuf,pcValue, Key: PChar;
  pTranslate : Pointer
  dwLanguage, dwCodePage : DWORD;
begin
  sAppName := Application.ExeName;
  iAppSize:= GetFileVersionInfoSize(PChar(sAppName),iAppSize);
  if (iAppSize > 0) then
  begin
    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, '\VarFileInfo\Translation', pTranslate, iAppSize);
      dwLanguage := LoWord(PInteger(pTranslate)^);
      dwCodePage := HiWord(PInteger(pTranslate)^);
      Key:= PChar(Format('\StringFileInfo\%.8x\' + sVersionType, [(dwLanguage shl 16) or dwCodePage]));
      if VerQueryValue(pcBuf, Key, Pointer(pcValue),iLenOfValue) then
        FVersionInfo[i] := pcValue;
    end;
    FreeMem(pcBuf,iAppSize);
  end;
end;
0
 
LVL 40

Author Comment

by:Richard Quadling
ID: 8282891
Thanks for that. Long time closed question too.
0
 

Expert Comment

by:dicktse
ID: 8287682
welcome... i just want to share my knowledge to people who are searching for this topic~
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

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

Suggested Solutions

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
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…
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

838 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