I'm loading package at runtime via LoadPackage()
. Let's say after load I want to check the version of the package to ensure it's the newest. How can I do that?
Asked
Active
Viewed 2,258 times
2

JustMe
- 2,329
- 3
- 23
- 43
-
2u may consider unit versioning: http://stackoverflow.com/questions/5251165 – Arioch 'The Oct 23 '12 at 06:21
1 Answers
7
A package is just a special type of dll, So you can use the GetFileVersion
function defined in the SysUtils unit, this function returns the most significant 32 bits of the version number. so does not include the release and/or build numbers.
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils;
Var
FileVersion : Cardinal;
begin
try
FileVersion:=GetFileVersion('C:\Bar\Foo.bpl');
Writeln(Format('%d.%d',[FileVersion shr 16, FileVersion and $FFFF]));
Readln;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
If you want retrieve the full version number (with release and build numbers included) you can use the GetFileVersionInfoSize
, VerQueryValue
and GetFileVersionInfo
WinApi functions.
function GetFileVersionStr(const AFileName: string): string;
var
FileName: string;
LinfoSize: DWORD;
lpdwHandle: DWORD;
lpData: Pointer;
lplpBuffer: PVSFixedFileInfo;
puLen: DWORD;
begin
Result := '';
FileName := AFileName;
UniqueString(FileName);
LinfoSize := GetFileVersionInfoSize(PChar(FileName), lpdwHandle);
if LinfoSize <> 0 then
begin
GetMem(lpData, LinfoSize);
try
if GetFileVersionInfo(PChar(FileName), lpdwHandle, LinfoSize, lpData) then
if VerQueryValue(lpData, '\', Pointer(lplpBuffer), puLen) then
Result := Format('%d.%d.%d.%d', [
HiWord(lplpBuffer.dwFileVersionMS),
LoWord(lplpBuffer.dwFileVersionMS),
HiWord(lplpBuffer.dwFileVersionLS),
LoWord(lplpBuffer.dwFileVersionLS)]);
finally
FreeMem(lpData);
end;
end;
end;

RRUZ
- 134,889
- 20
- 356
- 483
-
Thanks for clarifying how to translate FileVersion to more readable form :-) – JustMe Oct 22 '12 at 20:08
-
5Since the file is already loaded in memory, it is actually more efficient and more accurate to access its `RT_RESOURCE` resource directly, such as with `TResourceStream`, instead of using `GetFileVersionInfo()`, at least as far as the version number is concerned since it is static data. – Remy Lebeau Oct 22 '12 at 21:44
-
-
Microsoft doesn't want you to access the `RT_VERSION` resource directly, mainly because `GetFileVersionInfo()` does some dynamic data hookups that `VerQueryValue()` looks for. So Microsoft does not really document how to access the resource directly. But if the .exe file is inaccessible or modified, `GetFileVersionInfo()` can return bad data, so it may be desirable to access the resource directly since it is already in memory... – Remy Lebeau Oct 23 '12 at 22:58
-
... it is safe to [access the resource data directly](http://stackoverflow.com/questions/1717844/how-to-determine-delphi-application-version), as long as you account for one caveat - you have to dynamically allocate a memory block and copy the resource data into it before passing it to `VerQueryValue()`, otherwise it will crash with a memory access error. – Remy Lebeau Oct 23 '12 at 22:59