Delphi 从已编译的可执行文件/包中提取ProductVersion
在项目选项中,可以为已编译文件设置一些信息,如:Delphi 从已编译的可执行文件/包中提取ProductVersion,delphi,delphi-xe7,Delphi,Delphi Xe7,在项目选项中,可以为已编译文件设置一些信息,如: 公司名称 文件描述 文件版本 内部名称 法律权利 商标 原始文件名 产品名称 产品版本 评论 我从运行时的编译文件(exe/bpl)中知道,但我不知道如何提取这些额外信息 特别是,我希望获得ProductVersion值 下面是从可执行文件(或给定其文件名的任何文件)中获取ProductVersion的代码: 类型 TLangAndCodePage=记录 语言:单词; wCodePage:WORD; 结束; PLangAndCodePage=
- 公司名称
- 文件描述
- 文件版本
- 内部名称
- 法律权利
- 商标
- 原始文件名
- 产品名称
- 产品版本
- 评论
下面是从可执行文件(或给定其文件名的任何文件)中获取ProductVersion的代码:
类型
TLangAndCodePage=记录
语言:单词;
wCodePage:WORD;
结束;
PLangAndCodePage=^TLangAndCodePage;
程序TForm1.按钮1单击(发送方:TObject);
变量
InfoSize:整数;
ValueSize:DWORD;
假人:德沃德;
VerInfo:指针;
LangAndCodePage:PLangAndCodePage;
Ptr:PLangAndCodePage;
翻译字节:UINT;
I:整数;
子块:字符串;
子块缓冲区:PChar;
开始
InfoSize:=GetFileVersionInfoSize(PChar(Application.ExeName),Dummy);
如果InfoSize为0,则开始
GetMem(VerInfo,InfoSize);
尝试
如果GetFileVersionInfo(PChar(Application.ExeName),则为0,
InfoSize,VerInfo)然后开始
VerQueryValue(VerInfo,
“\VarFileInfo\Translation”,
指针(LangAndCodePage),
翻译细胞);
Ptr:=LangAndCodePage;
对于I:=0到(TranslateBytes div SizeOf(TLangAndCodePage))-1不开始
子块:=格式(“\StringFileInfo\%04.4X%04.4X\ProductVersion”,
[Ptr.w语言,Ptr.w代码页];
备注1.行.添加(子块);
VerQueryValue(VerInfo,
PChar(子块),
指针(子块缓冲区),
价值大小);
Memo1.Lines.Add('ProductVersion=“”+SubBlockBuffer+”);
公司(Ptr);
结束;
结束;
最后
FreeMem(VerInfo,InfoSize);
结束;
结束;
结束;
首先查询可用语言,然后遍历所有可用语言,从而生成代码
子块
实际上是要查询的值的一种路径。在这里,您可以看到我包含了您要求的ProductVersion
。还有其他预定义的值。见微软
您应该添加我忽略的错误测试,例如简单性。您看到这个问题了吗@Charles Henri:这是一个不同的问题,但我注意到Jiri Krivanek的回答也适用于我的问题,其中最多可以存储两个产品版本记录。第一个作为数字(2个DWORDs)存储在
TVSFixedFileInfo
中,第二个作为字符串存储在StringFileInfo
的ProductVersion
键下。后者可以不限于数字,还可以包含其他信息,如BETA或RC1。@彼得沃尔夫:我正在查找存储在StringFileInfo
中的区域设置ID$0409
(我想…)但我在哪里可以找到关于这两种文件信息的一些信息呢?请参阅官方MS文档以获取我已经发布的资源。另请参见文档导航窗格中的子类别块。注意:与在不知道其名称的情况下枚举块中的所有值相比,这几乎是微不足道的事情。同样地,ProductVersion
也不能保证存在于StringFileInfo
块中。
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;