gpt4 book ai didi

delphi - 更改可执行文件中的内部版本号

转载 作者:行者123 更新时间:2023-12-03 15:14:07 29 4
gpt4 key购买 nike

我希望更改可执行文件的版本信息中的内部版本号(VersionLS 的低位)。所以,我应该阅读VS_VERSIONINFO结构,更改内部版本号,然后将其更新回 PE。

我正在使用此代码作为基础:https://stackoverflow.com/a/7999813/1970843 。这段代码非常适合更改 VS_FIXEDFILEINFO数据,但它不会更改(也不会访问) StringFileInfo信息。

我很确定我应该在 VERSIONHEADER 打包记录中包含一些内容以添加 VS_VERSIONINFO 的 Children 条目,但我不知 Prop 体如何执行此操作。这是我到目前为止所拥有的:

type
StringStruc = Packed Record
wLength: Word;
wValueLength: Word;
wType: Word;
//szKey: ?;
//Value: ?;
End;

StringTable = Packed Record
wLength: Word;
wValueLength: Word;
wType: Word;
szKey: Array[0..8] Of WideChar;
Children: StringStruc;
End;

StringFileInfo = Packed Record
wLength: Word;
wValueLength: Word;
wType: Word;
szKey: Array[0..14] Of WideChar; // 'STRINGFILEINFO'
Children: StringTable;
End;

VERSIONHEADER = Packed Record
wLength: Word;
wValueLength: Word;
wType: Word;
szKey: Array[0..16] Of WideChar; // 'VS_VERSION_INFO'
Version: VS_FIXEDFILEINFO;
Children: StringFileInfo;
End;

...

var VersionHandle, VersionRes: THandle;
VersionSize: Cardinal;
Version: Array Of AnsiChar;
Ver: ^VERSIONHEADER;
Begin
VersionSize := GetFileVersionInfoSize(PChar(sExe), VersionHandle);

SetLength(Version, VersionSize);
Ver := Pointer(Version);
GetFileVersionInfo(PChar(sExe), 0, VersionSize, Ver);

因此,信息似乎正确到达第一个 StringStruc。但由于 szKey 和 Value 都不是固定大小,我不知道如何正确定义我的打包记录(是否可能?)来获取这些值。我在数组方面也遇到了麻烦......我该如何定义它们?按照我的做法,我只是在每个 Struc 上获取第一个 Children。请注意,我忽略了填充...这样可以吗?

感谢任何帮助。我在这里所做的大部分工作都是通过反复试验,所以我不太明白发生了什么。

PS:我仍在研究这个问题,所以我可能会经常更新这篇文章。

最佳答案

感谢您的关注和帮助。我在这里找到了一个现成的解决方案。事实上,它就在我链接到的问题的评论中(我真丢脸!)。

它基于 Colin Wilson 的库。它使用指针算术来提取和写入信息,因此,这是困难的(也许是唯一的)方式。 Jason Penny 还提供了一个关于如何使用该库的很好的示例: SetVersion 。由于我使用的是 D7,因此我从 here 下载了 Colin Wilson 的库。 (在资源实用程序下),但可以使用更新的版本,使用 UnicodeString 和更好的指针算术 here .

这是我现在的实际实现:

uses ..., unitResourceVersionInfo, unitPEFile;

...

var VersionInfo: TVersionInfoResourceDetails;
PEResModule: TPEResourceModule;
VersionNumber: ULARGE_INTEGER;
sVersion: String;
I: Integer;
Begin
PEResModule := TPEResourceModule.Create;
Try
PEResModule.LoadFromFile(sExe);

For I := 0 To PEResModule.ResourceCount - 1 Do Begin
If PEResModule.ResourceDetails[I] Is TVersionInfoResourceDetails Then Begin
VersionInfo := (PEResModule.ResourceDetails[I] As TVersionInfoResourceDetails);
Break;
End;
End;

VersionNumber.LowPart := MakeLong(NewBuildNumber, HiWord(VersionInfo.FileVersion.LowPart));
VersionNumber.HighPart := VersionInfo.FileVersion.HighPart;
VersionInfo.FileVersion := VersionNumber;
VersionInfo.ProductVersion := VersionNumber;

VersionInfo.CodePage := $04e4;

sVersion := Format('%d.%d.%d.%d', [HiWord(VersionInfo.FileVersion.HighPart), LoWord(VersionInfo.FileVersion.HighPart), HiWord(VersionInfo.FileVersion.LowPart), LoWord(VersionInfo.FileVersion.LowPart)]);
VersionInfo.SetKeyValue('FileVersion', sVersion);

PEResModule.SaveToFile(ChangeFileExt(sExe, '.exe2'));

Finally
FreeAndNil(PEResModule);
End;
End;

代码页行是由于库中的错误(我相信是这样)造成的。它不会读取代码页(为 0),因此,当您保存回来时,它会显示为 0。

关于delphi - 更改可执行文件中的内部版本号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21734035/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com