Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 445
  • Last Modified:

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

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
Richard Quadling
Asked:
Richard Quadling
  • 5
  • 2
  • 2
  • +3
1 Solution
 
EpsylonCommented:
0
 
Richard QuadlingSenior Software DeverloperAuthor Commented:
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
 
FrodoBegginsCommented:
You can use GetFileVersionInfo and VerQueryValue functions. Or use any kind of component - like TVersionInfo from the RX Components Suite
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
bozo7Commented:
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
 
bozo7Commented:
version.caption referenced above. Version is a TLabel.

Ross
0
 
FelixinCommented:
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
 
Richard QuadlingSenior Software DeverloperAuthor Commented:
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
 
Richard QuadlingSenior Software DeverloperAuthor Commented:
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
 
Richard QuadlingSenior Software DeverloperAuthor Commented:
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
 
FelixinCommented:
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
 
dicktseCommented:
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
 
Richard QuadlingSenior Software DeverloperAuthor Commented:
Thanks for that. Long time closed question too.
0
 
dicktseCommented:
welcome... i just want to share my knowledge to people who are searching for this topic~
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

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.

  • 5
  • 2
  • 2
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now