Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

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

Posted on 2001-07-02
13
Medium Priority
?
442 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
[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
  • 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
Technology Partners: 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 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 150 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

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

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

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
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…
Sometimes it takes a new vantage point, apart from our everyday security practices, to truly see our Active Directory (AD) vulnerabilities. We get used to implementing the same techniques and checking the same areas for a breach. This pattern can re…
In this video, Percona Director of Solution Engineering Jon Tobin discusses the function and features of Percona Server for MongoDB. How Percona can help Percona can help you determine if Percona Server for MongoDB is the right solution for …
Suggested Courses

688 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