Fabrizio
Fabrizio

Reputation: 8043

Extracting the ProductVersion from the compiled executable/package

In the Project Options, there are some informations that can be set for the compiled file, like:

I know how to extract the file version from the compiled file (exe/bpl) at runtime, but I don't know how to extract these extra informations.

In particular, I would like to get the ProductVersion value

Project Options window displaying the Version Info settings

Upvotes: 1

Views: 1707

Answers (1)

fpiette
fpiette

Reputation: 12292

Here after is the code to get the ProductVersion out of the executable file (Or any file given his file name):

type
    TLangAndCodePage = record
        wLanguage : WORD;
        wCodePage : WORD;
    end;
    PLangAndCodePage = ^TLangAndCodePage;

    procedure TForm1.Button1Click(Sender: TObject);
    var
        InfoSize        : Integer;
        ValueSize       : DWORD;
        Dummy           : DWORD;
        VerInfo         : Pointer;
        LangAndCodePage : PLangAndCodePage;
        Ptr             : PLangAndCodePage;
        TranslateBytes  : UINT;
        I               : Integer;
        SubBlock        : String;
        SubBlockBuffer  : PChar;
    begin
        InfoSize := GetFileVersionInfoSize(PChar(Application.ExeName), Dummy);
        if InfoSize <> 0 then begin
            GetMem(VerInfo, InfoSize);
            try
                if GetFileVersionInfo(PChar(Application.ExeName), 0,
                                      InfoSize, VerInfo) then begin
    
                    VerQueryValue(VerInfo,
                                  '\VarFileInfo\Translation',
                                  Pointer(LangAndCodePage),
                                  TranslateBytes);
    
                    Ptr := LangAndCodePage;
                    for I := 0 to (TranslateBytes div SizeOf(TLangAndCodePage)) - 1 do begin
                        SubBlock := Format('\StringFileInfo\%04.4X%04.4X\ProductVersion',
                                           [Ptr.wLanguage, Ptr.wCodePage]);
                        Memo1.Lines.Add(SubBlock);
    
                        VerQueryValue(VerInfo,
                                      PChar(SubBlock),
                                      Pointer(SubBlockBuffer),
                                      ValueSize);
                        Memo1.Lines.Add('  ProductVersion="' + SubBlockBuffer + '"');
    
                        Inc(Ptr);
                    end;
                end;
            finally
                FreeMem(VerInfo, InfoSize);
            end;
        end;
    end;

The code first by querying the languages available and then iterate thru all languages available.

SubBlock is actually a kind of path for the value to query. Here you see I included ProductVersion you asked for. There are other predefined values. See Microsoft documentation.

You should add error testing that I omitted for example simplicity.

Upvotes: 3

Related Questions