Inno-Setup-issrc/Projects/Src/Setup.MsiFunc.pas

91 lines
3.1 KiB
ObjectPascal
Raw Permalink Normal View History

unit Setup.MsiFunc;
{
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;
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);
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.