delphi – 在可执行文件中更改内部版本号
我想在可执行文件的版本信息中更改构建号(VersionLS的低位).所以,我应该阅读
VS_VERSIONINFO结构,更改内部版本号,然后将其更新回PE.
我正在使用此代码作为基础:https://stackoverflow.com/a/7999813/1970843.此代码非常适合更改VS_FIXEDFILEINFO数据,但它不会更改(也不访问)StringFileInfo信息. 我很确定我应该在VERSIONHEADER打包记录中包含一些内容来添加VS_VERSIONINFO的Children条目,但我不知道具体如何做到这一点.这是我到目前为止: 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),VersionSize,Ver); 因此,信息似乎正确地到达第一个StringStruc.但由于szKey和Value都不是固定大小,我不知道如何正确定义我的Packed Record(甚至可能?)来获取这些值.我也遇到阵列问题……如何定义它们?我正在做的方式,我只是在每个Struc上得到第一个孩子.请注意,我忽略了填充…这可以吗? 任何帮助表示赞赏.我在这里所做的大部分工作都是经过反复试验,所以我真的不明白发生了什么. PS:我还在努力,所以我可能经常更新这篇文章. 解决方法
感谢您的关注和帮助.我在SO上找到了一个现成的解决方案.事实上,正是在我对这个问题的评论中(对我感到羞耻!).
它基于Colin Wilson的库.它使用指针算法来提取和写入信息,因此,很难(也许是唯一的)方式.还有一个关于如何使用Jason Penny库的一个很好的例子:SetVersion.由于我使用D7,我从here(在Resource Utilities下)下载了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. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |