2024-08-03 20:33:25 +02:00
|
|
|
unit Setup.MsiFunc;
|
2020-12-03 22:33:01 +01:00
|
|
|
|
|
|
|
{
|
|
|
|
Inno Setup
|
|
|
|
Copyright (C) 1997-2020 Jordan Russell
|
|
|
|
Portions by Martijn Laan
|
|
|
|
For conditions of distribution and use, see LICENSE.TXT.
|
|
|
|
|
|
|
|
MSI functions
|
|
|
|
}
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
function IsMsiProductInstalled(const UpgradeCode: String; const PackedMinVersion: Int64; var ErrorCode: Cardinal): Boolean;
|
|
|
|
|
|
|
|
implementation
|
|
|
|
|
|
|
|
uses
|
2024-08-04 19:59:25 +02:00
|
|
|
Windows, SysUtils, Shared.CommonFunc, PathFunc, Shared.VerInfoFunc;
|
2020-12-03 22:33:01 +01:00
|
|
|
|
|
|
|
var
|
|
|
|
MsiLoaded: Boolean;
|
|
|
|
MsiLibrary: HMODULE;
|
|
|
|
MsiEnumRelatedProductsFunc: function(lpUpgradeCode: PChar; dwReserved, iProductIndex: DWORD; lpProductBuf: PChar): UINT; stdcall;
|
|
|
|
MsiGetProductInfoFunc: function(szProduct, szAttribute, lpValueBuf: PChar; var pcchValueBuf: DWORD): UINT; stdcall;
|
|
|
|
MsiLibraryLastError, MsiEnumRelatedProductsFuncLastError, MsiGetProductInfoFuncLastError: Cardinal;
|
|
|
|
|
|
|
|
function IsMsiProductInstalled(const UpgradeCode: String; const PackedMinVersion: Int64; var ErrorCode: Cardinal): Boolean;
|
|
|
|
var
|
|
|
|
ProductCode: array[0..38] of Char;
|
|
|
|
VersionStringSize: DWORD;
|
|
|
|
VersionString: String;
|
|
|
|
VersionNumbers: TFileVersionNumbers;
|
|
|
|
PackedVersion: Int64;
|
|
|
|
begin
|
|
|
|
Result := False;
|
|
|
|
|
|
|
|
if not MsiLoaded then begin
|
|
|
|
MsiLibrary := SafeLoadLibrary(AddBackslash(GetSystemDir) + 'msi.dll', SEM_NOOPENFILEERRORBOX);
|
|
|
|
if MsiLibrary <> 0 then begin
|
|
|
|
MsiEnumRelatedProductsFunc := GetProcAddress(MsiLibrary, 'MsiEnumRelatedProductsW');
|
|
|
|
MsiEnumRelatedProductsFuncLastError := GetLastError;
|
|
|
|
MsiGetProductInfoFunc := GetProcAddress(MsiLibrary, 'MsiGetProductInfoW');
|
|
|
|
MsiGetProductInfoFuncLastError := GetLastError;
|
|
|
|
end else
|
|
|
|
MsiLibraryLastError := GetLastError;
|
|
|
|
MsiLoaded := True;
|
|
|
|
end;
|
|
|
|
|
|
|
|
if MsiLibrary = 0 then
|
|
|
|
ErrorCode := MsiLibraryLastError
|
|
|
|
else if not Assigned(MsiEnumRelatedProductsFunc) then
|
|
|
|
ErrorCode := MsiEnumRelatedProductsFuncLastError
|
|
|
|
else if not Assigned(MsiGetProductInfoFunc) then
|
|
|
|
ErrorCode := MsiGetProductInfoFuncLastError
|
|
|
|
else
|
|
|
|
ErrorCode := ERROR_SUCCESS;
|
|
|
|
if ErrorCode <> ERROR_SUCCESS then
|
|
|
|
Exit;
|
|
|
|
|
|
|
|
ErrorCode := MsiEnumRelatedProductsFunc(PChar(UpgradeCode), 0, 0, ProductCode);
|
|
|
|
if ErrorCode <> ERROR_SUCCESS then begin
|
|
|
|
if ErrorCode = ERROR_NO_MORE_ITEMS then
|
|
|
|
ErrorCode := ERROR_SUCCESS; { Not installed so should just return False without an error }
|
|
|
|
Exit;
|
|
|
|
end;
|
|
|
|
|
|
|
|
VersionStringSize := 16;
|
|
|
|
SetLength(VersionString, VersionStringSize);
|
|
|
|
ErrorCode := MsiGetProductInfoFunc(ProductCode, 'VersionString', PChar(VersionString), VersionStringSize);
|
|
|
|
if ErrorCode = ERROR_MORE_DATA then begin
|
2020-12-08 18:58:51 +01:00
|
|
|
Inc(VersionStringSize);
|
|
|
|
SetLength(VersionString, VersionStringSize);
|
2020-12-03 22:33:01 +01:00
|
|
|
ErrorCode := MsiGetProductInfoFunc(ProductCode, 'VersionString', PChar(VersionString), VersionStringSize);
|
|
|
|
end;
|
|
|
|
if ErrorCode <> ERROR_SUCCESS then
|
|
|
|
Exit;
|
|
|
|
SetLength(VersionString, VersionStringSize);
|
|
|
|
|
|
|
|
if not StrToVersionNumbers(VersionString, VersionNumbers) then begin
|
|
|
|
ErrorCode := ERROR_BAD_FORMAT;
|
|
|
|
Exit;
|
|
|
|
end;
|
|
|
|
|
|
|
|
PackedVersion := (Int64(VersionNumbers.MS) shl 32) or VersionNumbers.LS;
|
|
|
|
Result := PackedVersion >= PackedMinVersion;
|
|
|
|
ErrorCode := ERROR_SUCCESS;
|
|
|
|
end;
|
|
|
|
|
|
|
|
end.
|