[Setup]
AppName=My Application
AppVersion=1.5
CreateAppDir=no
[Code]
function GetFileVersionInfoSize(lptstrFilename: String; lpdwHandle: Integer): Integer;
external 'GetFileVersionInfoSizeW@version.dll stdcall delayload';
function GetFileVersionInfo(
lptstrFilename: String; dwHandle, dwLen: Integer; var lpData: Byte): Boolean;
external 'GetFileVersionInfoW@version.dll stdcall delayload';
function VerQueryValue(
var pBlock: Byte; lpSubBlock: String; var lplpBuffer: DWord;
var Len: Integer): Boolean;
external 'VerQueryValueW@version.dll stdcall delayload';
procedure RtlMoveMemoryAsString(Dest: string; Source: DWord; Len: Integer);
external 'RtlMoveMemory@kernel32.dll stdcall';
procedure RtlMoveMemoryAsBytes(Dest: array of Byte; Source: DWord; Len: Integer);
external 'RtlMoveMemory@kernel32.dll stdcall';
function GetFileVerInfo(FileName, VerName: String): String;
var
Len: Integer;
FileVerInfo: array of Byte;
Lang: array of Byte;
Buffer: DWord;
LangCodepage: string;
SubBlock: string;
begin
Result := '';
if FileExists(FileName) then
begin
Len := GetFileVersionInfoSize(FileName, 0);
if Len > 0 then
begin
SetArrayLength(FileVerInfo, Len);
if GetFileVersionInfo(FileName, 0, Len, FileVerInfo[0]) then
begin
if VerQueryValue(FileVerInfo[0], '\VarFileInfo\Translation', Buffer, Len) then
begin
if Len >= 4 then
begin
SetArrayLength(Lang, 4);
RtlMoveMemoryAsBytes(Lang, Buffer, 4);
LangCodepage :=
Format('%.2x%.2x%.2x%.2x', [Lang[1], Lang[0], Lang[3], Lang[2]]);
SubBlock := Format('\%s\%s\%s', ['StringFileInfo', LangCodepage, VerName]);
if VerQueryValue(FileVerInfo[0], SubBlock, Buffer, Len) then
begin
SetLength(Result, Len - 1);
RtlMoveMemoryAsString(Result, Buffer, (Len - 1) * 2);
end;
end;
end;
end;
end;
end;
end;
procedure InitializeWizard;
var
Test: String;
begin
Test := GetFileVerInfo( 'C:\MyEXE.exe', 'FileDescription' );
MsgBox(Test, mbInformation, MB_OK);
end;