Solved

Using the Project Options version information...

Posted on 1998-10-19
7
285 Views
Last Modified: 2010-04-03
I hate the Help files!  They tell me that I can use the Version information that I set in Project|Options, but when I try the example given, it bombs.  How do I reference the Version info set in Project|Options?!?!
0
Comment
Question by:Raven1155
  • 4
  • 2
7 Comments
 
LVL 12

Expert Comment

by:rwilson032697
Comment Utility
Here is the source for a freeware component called verslab (from DSP...) It should show you how to do it...


----------------------
unit verslab;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
    TVersionResources = (vrCompanyName, vrFileDescription, vrFileVersion,
                         vrInternalName, vrLegalCopyright, vrOriginalFilename,
                         vrProductName, vrProductVersion, vrComments, vrFlags);

  TVersionLabel = class(TCustomLabel)
  private
    { Private declarations }
    FVersionResource: TVersionResources;
    FInfoPrefix: string;
    FShowInfoPrefix: boolean;
    FVersionResourceKey: string;
    FLangCharset: string;

    procedure SetupInfoPrefix;
    procedure SetupResourceKey;
    function GetStringFileInfo(Buffer: Pchar; size: integer): string;
    function GetFixedFileInfo(Buffer: PChar; size: integer): string;
    function GetInfo: string;
    procedure SetupCaption;
  protected
    { Protected declarations }
    procedure SetInfoPrefix(Value: String);
    function GetInfoPrefix: string;
    procedure SetVersionResource(Value: TVersionResources);
    procedure SetShowInfoPrefix(Value: boolean);
    procedure SetVersionResourceKey(Value: string);
    procedure SetLangCharset(Value: string);
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

  published
    { Published declarations }
    property VersionResource: TVersionResources read FVersionResource
                                                write SetVersionResource;
    property VersionResourceKey: string read FVersionResourceKey
                                         write SetVersionResourceKey;
    property InfoPrefix: String read GetInfoPrefix write SetInfoPrefix;
    property ShowInfoPrefix: boolean read FShowInfoPrefix write SetShowInfoPrefix;
    property LangCharset: string read FLangCharset write SetLangCharset;
    property WordWrap;
    property Align;
    property Color;
    property Font;
    property AutoSize;
    property Alignment;
    property ParentFont;
  end;

const
    {The order of this array must be the same as the VersionResources
    enum type as that is used for the index lookup}
    VersionLookup: array[TVersionResources, 0..1] of string = (
                    ('CompanyName', 'Company Name:'), {SKIP}
                    ('FileDescription', 'File Description:'), {SKIP}
                    ('FileVersion', 'File Version:'), {SKIP}
                    ('InternalName', 'Internal Name:'), {SKIP}
                    ('LegalCopyright', 'Legal Copyright:'), {SKIP}
                    ('OriginalFilename', 'Original Filename:'), {SKIP}
                    ('ProductName', 'Product Name:'), {SKIP}
                    ('ProductVersion', 'Product Version:'), {SKIP}
                    ('Comments', 'Comments:'), {SKIP}
                    ('Flags', 'Flags:')); {SKIP}

procedure Register;

implementation

{$IFNDEF VER90}
Type
  LongWord = Integer;
{$ENDIF}

procedure Register;
begin
  RegisterComponents('Samples', [TVersionLabel]); {SKIP}
end;

constructor TVersionLabel.Create(AOwner: TComponent);
begin
    inherited Create(AOwner);
    WordWrap := false;
    Autosize := true;
    ShowInfoPrefix := true;
    LangCharset :='-1';   {-1 = auto detect}
    VersionResource := vrFileVersion;
end;

destructor TVersionLabel.Destroy;
begin
    inherited Destroy;
end;

procedure TVersionLabel.SetVersionResource(Value: TVersionResources);
begin
    FVersionResource := Value;
    SetupResourceKey;
    SetupInfoPrefix;
end;

procedure TVersionLabel.SetupInfoPrefix;
var s: string;
begin
    s := VersionLookup[FVersionResource, 1];
    InfoPrefix := s;
end;

procedure TVersionLabel.SetupResourceKey;
var s: string;
begin
    s := VersionLookup[FVersionResource, 0];
    VersionResourceKey := s;
end;

function TVersionLabel.GetFixedFileInfo(Buffer: PChar; size: integer): string;
var
  ValLen: LongWord;
  FixedFileInfo: PVSFixedFileInfo;
begin
    if VerQueryValue(buffer, '\', Pointer(FixedFileInfo), ValLen) then
    begin
        Result := '';
        if (ValLen > 1) then
        begin
            if FixedFileInfo.dwFileFlags and VS_FF_DEBUG <> 0 then
                Result := Result+', Debug Build'; {SKIP}
            if FixedFileInfo.dwFileFlags and VS_FF_PRERELEASE <> 0 then
                Result := Result+', Pre-Release Build'; {SKIP}
            if FixedFileInfo.dwFileFlags and VS_FF_PATCHED <> 0 then
                Result := Result+', Patched Build'; {SKIP}
            if FixedFileInfo.dwFileFlags and VS_FF_PRIVATEBUILD <> 0  then
                Result := Result+', Private Build'; {SKIP}
            if FixedFileInfo.dwFileFlags and VS_FF_INFOINFERRED <> 0  then
                Result := Result+', InfoInferred'; {SKIP}
            if FixedFileInfo.dwFileFlags and VS_FF_SPECIALBUILD <> 0  then
                Result := Result+', Special Build'; {SKIP}

            if result <> '' then
                if Result[1] = ',' then Delete(Result, 1, 2);
        end;
    end
    else Result := '< Error retrieving version info >'; {SKIP}
end;

function TVersionLabel.GetStringFileInfo(Buffer: Pchar; size: integer): string;
var vallen, Translen: LongWord;
    VersionPointer, TransBuffer: pchar;
    Temp: integer;
    CalcLangCharSet: string;
begin
    if FLangCharSet = '-1' then
    begin
        VerQueryValue(buffer, '\VarFileInfo\Translation', {SKIP}
                        pointer(TransBuffer), TransLen);
        if TransLen >= 4 then
        begin
            StrLCopy(@temp, TransBuffer, 2);
            CalcLangCharSet:=IntToHex(temp, 4);
            StrLCopy(@temp, TransBuffer+2, 2);
            CalcLangCharSet := CalcLangCharSet+IntToHex(temp, 4);
            FLangCharSet := CalcLangCharSet;
        end
        else
        begin
            Result := '< Error retrieving translation info >'; {SKIP}
            exit;
        end;
    end;

    if VerQueryValue(buffer, pchar('\StringFileInfo\'+FLangCharSet+'\'+ {SKIP}
                     VersionResourceKey),
                     pointer(VersionPointer), vallen) then
    begin
        if (Vallen > 1) then
        begin
            SetLength(Result, vallen);
            StrLCopy(Pchar(Result), VersionPointer, vallen);
        end
        else Result := '< No Version Info >'; {SKIP}
    end
    else result := '< Error retrieving version info >'; {SKIP}
end;

function TVersionLabel.GetInfo: string;
var dump : LongWord;
    size: integer;
    buffer: pchar;
begin
    if csDesigning in Self.ComponentState then result := '< No design info >' {SKIP}
    else
    begin
        size := GetFileVersionInfoSize(pchar(Application.Exename), dump);
        if  size = 0 then
        begin
            Result := '< No Data Available >'; {SKIP}
        end
        else
        begin
            buffer := StrAlloc(size+1);
            try
                if not GetFileVersionInfo(Pchar(Application.Exename), 0,
                        size, buffer) then
                    result := '< Error retrieving version info >' {SKIP}
                else
                begin
                    if FVersionResource = vrFlags then
                        Result := GetFixedFileInfo(buffer, size)
                    else Result := GetStringFileInfo(buffer, size);
                end;
            finally
                StrDispose(Buffer);
            end;
        end;
    end;
    if ShowInfoPrefix then Result := InfoPrefix+' '+Result;
end;

procedure TVersionLabel.SetInfoPrefix(Value: String);
begin
    if FInfoPrefix = Value then exit;
    FInfoPrefix := Value;
    {The caption needs to be recalculated everytime the prefix is
    changed, otherwise the detaults override the user specified one}
    SetupCaption;
end;

procedure TVersionLabel.SetVersionResourceKey(Value: string);
begin
    if FVersionResourceKey = Value then exit;
    FVersionResourceKey := Value;
    InfoPrefix := Value;
end;

function TVersionLabel.GetInfoPrefix: string;
begin
    result := FInfoPrefix;
end;

procedure TVersionLabel.SetShowInfoPrefix(Value: boolean);
begin
    if FShowInfoPrefix = value then exit;
    FShowInfoPrefix := Value;
    SetupCaption;
end;

procedure TVersionLabel.SetLangCharset(Value: string);
begin
    if FLangCharSet = Value then exit;
    FLangCharSet := Value;
    SetupCaption;
end;

procedure TVersionLabel.SetupCaption;
begin
    Caption := GetInfo;
end;


end.


0
 

Expert Comment

by:bome
Comment Utility
Hi,
I never understand, why ALL version readers have problems with the language the version is compiled. It's very easy to get the available language as well. It IS possible with delphi to include several version resources, but then they have to be in different languages. My function is short and reads the version string of the first language.
So you don't worry in what language your version resource is compiled - normally the language information doesn't matter anyway. (I compile my projects under different OS's in different languages).


function getVersionStringFromFile(const sAppName:String):String;
var
  iAppSize, iLenOfValue: integer;
  pcBuf,pcValue: PChar;
begin
  result:='';
  iAppSize:= GetFileVersionInfoSize(PChar(sAppName),iAppSize);
  if iAppSize > 0 then
  begin
   pcBuf := AllocMem(iAppSize);
   GetFileVersionInfo(PChar(sAppName),0,iAppSize,pcBuf);
   if VerQueryValue(pcBuf, PChar('\VarFileInfo\Translation'),
      Pointer(pcValue), iLenOfValue) then
    if VerQueryValue(pcBuf, PChar('\StringFileInfo\'
      +IntToHex(PWord(pcValue)^,4)+IntToHex(PWord(pcValue+2)^,4)
      +'\FileVersion'),Pointer(pcValue), iLenOfValue) then
     setString(result,PChar(pcValue),strlen(pcValue));
   FreeMem(pcBuf,iAppSize);
  end;
end;

function getVersionString:String;
begin
  result:=getVersionStringFromFile(Application.ExeName);
end;

0
 
LVL 12

Expert Comment

by:rwilson032697
Comment Utility
Hi bome,

It matters because you can translate the version information!

Cheers,

Raymond.
0
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:Raven1155
Comment Utility
The answer (and the comment) provided here seem to both be for how to get the information off of an .EXE file.  That was not the question...

The D4 help file shows what it claims is a way to set the values for the Version #, Copyright, App Name, etc. on an About dialog from the values set at Design time using Project|Options.  I can't figure out why the example they show doesn't work.  I am asking if there is a way to access these values at run time so the the About dialog is automatically updated using the values set using Project|Options!!

0
 
LVL 12

Expert Comment

by:rwilson032697
Comment Utility
The component source I posted allows you to show on a dialog information from the version info.

Reading your restatement of the question seems to make it more ambiguous... Are you saying that you want it to work at design time?

If you just want version information shown on a form at runtime then the answer I posted is indeed the (well, an) answer.

Cheers,

Raymond.
0
 

Author Comment

by:Raven1155
Comment Utility
I may be shooting the messenger...

Reviewing the help topic that got me going on this showed that it was a component (user written) that they are talking about.  So my original premise that the help file says there's a way to do it was wrong.  Sorry!

However, it boggles my mind that the version information is not available AS PROPERTIES OF THE APPLICATION (or some-such) without having to read the file header (which is what that code seems to do)!

So, RWilson, if you'd be so kind as to send something (anything) as an ANSWER (vice a comment) so that I can credit you for it, I will slither off and see what OTHER trouble I can get into!

Thanks!
0
 
LVL 12

Accepted Solution

by:
rwilson032697 earned 50 total points
Comment Utility
And it was so...

Cheers,

Raymond.
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

771 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

11 Experts available now in Live!

Get 1:1 Help Now