从编译的 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.
您应该添加我为简单起见而省略的错误测试。
在项目选项中,有一些可以为编译后的文件设置的信息,如:
- 公司名称
- 文件描述
- 文件版本
- 内部名称
- 合法版权
- 合法商标
- 原始文件名
- 产品名称
- 产品版本
- 评论
我知道 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.
您应该添加我为简单起见而省略的错误测试。