Hallo,
ich habe dieses Thema 2006 bereits einmal vorgetragen, damals konnte niemand so richtig helfen. Es geht erneut darum, in eine DLL über ein Delphi-Programm Versionsinformationen zu schreiben. Gemeint sind damit die Informationen, welche später in dem Fenster aus dem Screenshot erscheinen.
Es geht
nicht darum, diese Informationen zu lesen. Ich verwende Delphi XE2. Bei einem frischen DLL Projekt ist Delphi XE2 (unter Windows 7, 64 Bit) offenbar auch nicht in der Lage diese Versionsinformationen zu schreiben. Die Versionsinformationen kann man ja im Projekt unter "Projekt" -> "Optionen..." -> "Versionsinformationen" festlegen. Erzeuge ich nach dem festlegen der Informationen das Projekt neu, dann sieht das Eigenschaftsfenster weiterhin so aus, wie im Screenshot gezeigt.
ABER: Eigentlich möchte ich diese Informationen auch nicht auf diese Art einbetten. Vielmehr möchte ich DLLs (und EXE-Dateien) nachträglich Versionieren. Das dient dazu, dass die Versionsinfos Projektweit gleich gehalten werden sollen. DDevExtensions kommen nicht in Frage, weil: 1. Delphi die Infos bei DLLs wie oben beschrieben nicht schreibt und 2. einige DLLs des Projekts nicht mit Delphi erstellt werden.
Die Google Suche erschöpft sich sehr schnell. Dort geht es meist ums lesen der Versionsinformationen. Ich möchte die Informationen aber schreiben. Falls jemand ein Kommandozeilentool für die Manipulation der Versionsinformationen kennt, wäre das auch eine Hilfe. Unter
4coder.org/delphi-source-code/914/ habe ich noch eine alte Version des XNResourceEditors ausgegraben, weil auf der offiziellen Webseite alle Links tot sind. Offenbar ist das aber nur die GUI. Zumindest kann ich mit dem Keyword "UpdateResource" nichts brauchbares finden.
Anbei noch mein aktueller Stand der Funktion, die ich zur Zeit verwende. Bei EXE-Dateien wird zumindest die Dateiversion, aber nicht die Produktversion geschrieben. Auch das verstehe ich nicht so ganz. Meine Vermutung geht irgendwie in Richtung fehlendes 32-Bit Alignment. Fehlt da eventuell noch was? Ich muss sagen, dass ich nicht ganz verstehe, was hier bei der Eigenschaft Padding1 und Padding2 gemeint ist:
msdn.microsoft.com/e...01%28v=vs.85%29.aspx
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87:
| function WriteVersionInfo(const FileName: string; Major, Minor, Release, Build: Word): Boolean; type VS_VERSIONINFO = packed record wLength: Word; wValueLength: Word; wType: Word; szKey: array[0..15] of WideChar; Padding1: Word; Value: VS_FIXEDFILEINFO; Padding2: Word; Children: Word; end;
var lHLib: Cardinal; lHRes: Cardinal; lHResLoad: Cardinal; lPResLock: Pointer; lSz: Cardinal; lPVersionInfo: ^VS_VERSIONINFO; lPt: Pointer; lHResUpd: Cardinal;
begin Result := False;
if FileExists(FileName) then begin lHLib := SafeLoadLibrary(PChar(FileName), SEM_FAILCRITICALERRORS);
if lHLib <> 0 then begin lPVersionInfo := nil; lSz := 0;
try lHRes := FindResource(lHLib, MakeIntResource(1), RT_VERSION);
if lHRes <> 0 then begin lHResLoad := LoadResource(lHLib, lHRes); lSz := SizeofResource(lHLib, lHRes);
if lHResLoad <> 0 then begin lPResLock := LockResource(lHResLoad); GetMem(lPt, lSz); Move(lPResLock^, lPt^, lSz); lPVersionInfo := lPt; end; end else GetMem(lpVersionInfo, SizeOf(VS_VERSIONINFO)); finally FreeLibrary(lHLib); end;
if Assigned(lPVersionInfo) then try lPVersionInfo^.Value.dwFileVersionMS := (Major shl 16) or Minor; lPVersionInfo^.Value.dwFileVersionLS := (Release shl 16) or Build; lPVersionInfo^.Value.dwProductVersionMS := (Major shl 16) or Minor; lPVersionInfo^.Value.dwProductVersionLS := (Release shl 16) or Build; lpVersionInfo^.wValueLength := SizeOf(VS_FIXEDFILEINFO);
lHResUpd := BeginUpdateResource(PChar(FileName), False);
if lHResUpd <> 0 then begin try Result := UpdateResource(lHResUpd, RT_VERSION, MakeIntResource(VS_VERSION_INFO), 0, lPVersionInfo, lSz); finally EndUpdateResource(lHResUpd, not Result); end; end; finally FreeMem(lPVersionInfo); end else raise Exception.CreateFmt('No version info found for %s', [FileName]); end else raise Exception.CreateFmt('Failed to load lib %s', [FileName]); end else raise Exception.CreateFmt('File %s does not exist', [FileName]); end; |