从编译的 executable/package 中提取 ProductVersion

Extracting the ProductVersion from the compiled executable/package

项目选项中,有一些可以为编译后的文件设置的信息,如:

我知道 how to extract the file version 在运行时从编译文件 (exe/bpl),但我不知道如何提取这些额外信息。

特别是,我想获得 ProductVersion

下面是从可执行文件(或给定其文件名的任何文件)中获取 ProductVersion 的代码:

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;

代码首先查询可用语言,然后遍历所有可用语言。

SubBlock其实就是一种查询值的路径。在这里你看到我包括了你要求的ProductVersion。还有其他预定义值。见微软 documentation.

您应该添加我为简单起见而省略的错误测试。