I appreciate your attention and help. I found a ready solution here on SO. In fact, it's in the comments to the very question I've linked to (shame on me!).
It's based on a library by Colin Wilson. It uses pointer arithmetic to extract and write the information, so, the hard (maybe only) way. There's also a nice example on how to use the library by Jason Penny: SetVersion. Since I'm using D7, I downloaded Colin Wilson's library from here (under Resource Utilities), but a more recent version, using UnicodeString and nicer pointer arithmetic, is available here.
This is the actual implementation I have now:
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;
The codepage line is due to a bug (I believe it is) in the library. It doesn't reads the codepage (comes 0), so, when you save back, it appears as 0.