mirror of
https://github.com/fergalmoran/DnsServer.git
synced 2025-12-22 09:29:50 +00:00
353 lines
10 KiB
Plaintext
353 lines
10 KiB
Plaintext
[Setup]
|
|
MinVersion=6.1sp1
|
|
|
|
// remove next line if you only deploy 32-bit binaries and dependencies
|
|
ArchitecturesInstallIn64BitMode=x64
|
|
|
|
// dependency installation requires ready page and ready memo to be enabled (default behaviour)
|
|
DisableReadyPage=no
|
|
DisableReadyMemo=no
|
|
|
|
// shared code for installing the dependencies
|
|
[Code]
|
|
// types and variables
|
|
type
|
|
TDependency = record
|
|
Filename: String;
|
|
Parameters: String;
|
|
Title: String;
|
|
URL: String;
|
|
Checksum: String;
|
|
ForceSuccess: Boolean;
|
|
InstallClean: Boolean;
|
|
RebootAfter: Boolean;
|
|
end;
|
|
|
|
InstallResult = (InstallSuccessful, InstallRebootRequired, InstallError);
|
|
|
|
var
|
|
MemoInstallInfo: String;
|
|
Dependencies: array of TDependency;
|
|
DelayedReboot, ForceX86: Boolean;
|
|
DownloadPage: TDownloadWizardPage;
|
|
|
|
procedure AddDependency(const Filename, Parameters, Title, URL, Checksum: String; const ForceSuccess, InstallClean, RebootAfter: Boolean);
|
|
var
|
|
Dependency: TDependency;
|
|
I: Integer;
|
|
begin
|
|
MemoInstallInfo := MemoInstallInfo + #13#10 + '%1' + Title;
|
|
|
|
Dependency.Filename := Filename;
|
|
Dependency.Parameters := Parameters;
|
|
Dependency.Title := Title;
|
|
|
|
if FileExists(ExpandConstant('{tmp}{\}') + Filename) then begin
|
|
Dependency.URL := '';
|
|
end else begin
|
|
Dependency.URL := URL;
|
|
end;
|
|
|
|
Dependency.Checksum := Checksum;
|
|
Dependency.ForceSuccess := ForceSuccess;
|
|
Dependency.InstallClean := InstallClean;
|
|
Dependency.RebootAfter := RebootAfter;
|
|
|
|
I := GetArrayLength(Dependencies);
|
|
SetArrayLength(Dependencies, I + 1);
|
|
Dependencies[I] := Dependency;
|
|
end;
|
|
|
|
function IsPendingReboot: Boolean;
|
|
var
|
|
Value: String;
|
|
begin
|
|
Result := RegQueryMultiStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager', 'PendingFileRenameOperations', Value) or
|
|
(RegQueryMultiStringValue(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\Session Manager', 'SetupExecute', Value) and (Value <> ''));
|
|
end;
|
|
|
|
function InstallProducts: InstallResult;
|
|
var
|
|
ResultCode, I, ProductCount: Integer;
|
|
begin
|
|
Result := InstallSuccessful;
|
|
ProductCount := GetArrayLength(Dependencies);
|
|
MemoInstallInfo := SetupMessage(msgReadyMemoTasks);
|
|
|
|
if ProductCount > 0 then begin
|
|
DownloadPage.Show;
|
|
|
|
for I := 0 to ProductCount - 1 do begin
|
|
if Dependencies[I].InstallClean and (DelayedReboot or IsPendingReboot) then begin
|
|
Result := InstallRebootRequired;
|
|
break;
|
|
end;
|
|
|
|
DownloadPage.SetText(Dependencies[I].Title, '');
|
|
DownloadPage.SetProgress(I + 1, ProductCount);
|
|
|
|
while True do begin
|
|
ResultCode := 0;
|
|
if ShellExec('', ExpandConstant('{tmp}{\}') + Dependencies[I].Filename, Dependencies[I].Parameters, '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode) then begin
|
|
if Dependencies[I].RebootAfter then begin
|
|
// delay reboot after install if we installed the last dependency anyways
|
|
if I = ProductCount - 1 then begin
|
|
DelayedReboot := True;
|
|
end else begin
|
|
Result := InstallRebootRequired;
|
|
MemoInstallInfo := Dependencies[I].Title;
|
|
end;
|
|
break;
|
|
end else if (ResultCode = 0) or Dependencies[I].ForceSuccess then begin
|
|
break;
|
|
end else if ResultCode = 3010 then begin
|
|
// Windows Installer ResultCode 3010: ERROR_SUCCESS_REBOOT_REQUIRED
|
|
DelayedReboot := True;
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
case SuppressibleMsgBox(FmtMessage(SetupMessage(msgErrorFunctionFailed), [Dependencies[I].Title, IntToStr(ResultCode)]), mbError, MB_ABORTRETRYIGNORE, IDIGNORE) of
|
|
IDABORT: begin
|
|
Result := InstallError;
|
|
MemoInstallInfo := MemoInstallInfo + #13#10 + ' ' + Dependencies[I].Title;
|
|
break;
|
|
end;
|
|
IDIGNORE: begin
|
|
MemoInstallInfo := MemoInstallInfo + #13#10 + ' ' + Dependencies[I].Title;
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if Result <> InstallSuccessful then begin
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
DownloadPage.Hide;
|
|
end;
|
|
end;
|
|
|
|
// Inno Setup event functions
|
|
procedure InitializeWizard;
|
|
begin
|
|
DownloadPage := CreateDownloadPage(SetupMessage(msgWizardPreparing), SetupMessage(msgPreparingDesc), nil);
|
|
end;
|
|
|
|
function PrepareToInstall(var NeedsRestart: Boolean): String;
|
|
begin
|
|
DelayedReboot := False;
|
|
|
|
case InstallProducts of
|
|
InstallError: begin
|
|
Result := MemoInstallInfo;
|
|
end;
|
|
InstallRebootRequired: begin
|
|
Result := MemoInstallInfo;
|
|
NeedsRestart := True;
|
|
|
|
// write into the registry that the installer needs to be executed again after restart
|
|
RegWriteStringValue(HKEY_CURRENT_USER, 'SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce', 'InstallBootstrap', ExpandConstant('{srcexe}'));
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function NeedRestart: Boolean;
|
|
begin
|
|
Result := DelayedReboot;
|
|
end;
|
|
|
|
function UpdateReadyMemo(const Space, NewLine, MemoUserInfoInfo, MemoDirInfo, MemoTypeInfo, MemoComponentsInfo, MemoGroupInfo, MemoTasksInfo: String): String;
|
|
begin
|
|
Result := '';
|
|
if MemoUserInfoInfo <> '' then begin
|
|
Result := Result + MemoUserInfoInfo + Newline + NewLine;
|
|
end;
|
|
if MemoDirInfo <> '' then begin
|
|
Result := Result + MemoDirInfo + Newline + NewLine;
|
|
end;
|
|
if MemoTypeInfo <> '' then begin
|
|
Result := Result + MemoTypeInfo + Newline + NewLine;
|
|
end;
|
|
if MemoComponentsInfo <> '' then begin
|
|
Result := Result + MemoComponentsInfo + Newline + NewLine;
|
|
end;
|
|
if MemoGroupInfo <> '' then begin
|
|
Result := Result + MemoGroupInfo + Newline + NewLine;
|
|
end;
|
|
if MemoTasksInfo <> '' then begin
|
|
Result := Result + MemoTasksInfo;
|
|
end;
|
|
|
|
if MemoInstallInfo <> '' then begin
|
|
if MemoTasksInfo = '' then begin
|
|
Result := Result + SetupMessage(msgReadyMemoTasks);
|
|
end;
|
|
Result := Result + FmtMessage(MemoInstallInfo, [Space]);
|
|
end;
|
|
end;
|
|
|
|
function NextButtonClick(const CurPageID: Integer): Boolean;
|
|
var
|
|
I, ProductCount: Integer;
|
|
Retry: Boolean;
|
|
begin
|
|
Result := True;
|
|
|
|
if (CurPageID = wpReady) and (MemoInstallInfo <> '') then begin
|
|
DownloadPage.Show;
|
|
|
|
ProductCount := GetArrayLength(Dependencies);
|
|
for I := 0 to ProductCount - 1 do begin
|
|
if Dependencies[I].URL <> '' then begin
|
|
DownloadPage.Clear;
|
|
DownloadPage.Add(Dependencies[I].URL, Dependencies[I].Filename, Dependencies[I].Checksum);
|
|
|
|
Retry := True;
|
|
while Retry do begin
|
|
Retry := False;
|
|
|
|
try
|
|
DownloadPage.Download;
|
|
except
|
|
if GetExceptionMessage = SetupMessage(msgErrorDownloadAborted) then begin
|
|
Result := False;
|
|
I := ProductCount;
|
|
end else begin
|
|
case SuppressibleMsgBox(AddPeriod(GetExceptionMessage), mbError, MB_ABORTRETRYIGNORE, IDIGNORE) of
|
|
IDABORT: begin
|
|
Result := False;
|
|
I := ProductCount;
|
|
end;
|
|
IDRETRY: begin
|
|
Retry := True;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
DownloadPage.Hide;
|
|
end;
|
|
end;
|
|
|
|
// architecture helper functions
|
|
function IsX64: Boolean;
|
|
begin
|
|
Result := not ForceX86 and Is64BitInstallMode;
|
|
end;
|
|
|
|
function GetString(const x86, x64: String): String;
|
|
begin
|
|
if IsX64 then begin
|
|
Result := x64;
|
|
end else begin
|
|
Result := x86;
|
|
end;
|
|
end;
|
|
|
|
function GetArchitectureSuffix: String;
|
|
begin
|
|
Result := GetString('', '_x64');
|
|
end;
|
|
|
|
function GetArchitectureTitle: String;
|
|
begin
|
|
Result := GetString(' (x86)', ' (x64)');
|
|
end;
|
|
|
|
function CompareVersion(const Version1, Version2: String): Integer;
|
|
var
|
|
Position, Number1, Number2: Integer;
|
|
begin
|
|
Result := 0;
|
|
while (Version1 <> '') or (Version2 <> '') do begin
|
|
Position := Pos('.', Version1);
|
|
if Position > 0 then begin
|
|
Number1 := StrToIntDef(Copy(Version1, 1, Position - 1), 0);
|
|
Delete(Version1, 1, Position);
|
|
end else if Version1 <> '' then begin
|
|
Number1 := StrToIntDef(Version1, 0);
|
|
Version1 := '';
|
|
end else begin
|
|
Number1 := 0;
|
|
end;
|
|
|
|
Position := Pos('.', Version2);
|
|
if Position > 0 then begin
|
|
Number2 := StrToIntDef(Copy(Version2, 1, Position - 1), 0);
|
|
Delete(Version2, 1, Position);
|
|
end else if Version2 <> '' then begin
|
|
Number2 := StrToIntDef(Version2, 0);
|
|
Version2 := '';
|
|
end else begin
|
|
Number2 := 0;
|
|
end;
|
|
|
|
if Number1 < Number2 then begin
|
|
Result := -1;
|
|
break;
|
|
end else if Number1 > Number2 then begin
|
|
Result := 1;
|
|
break;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{ Check if dotnet is installed }
|
|
function IsAspDotNetInstalled: Boolean;
|
|
var
|
|
ResultCode: Integer;
|
|
begin
|
|
Result := false;
|
|
Exec('cmd.exe', '/c dotnet --list-runtimes | find /n "Microsoft.AspNetCore.App 8.0.3"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
|
|
if ResultCode = 0 then
|
|
begin
|
|
Result := true;
|
|
end;
|
|
end;
|
|
|
|
function IsDotNetDesktopInstalled: Boolean;
|
|
var
|
|
ResultCode: Integer;
|
|
begin
|
|
Result := false;
|
|
Exec('cmd.exe', '/c dotnet --list-runtimes | find /n "Microsoft.WindowsDesktop.App 8.0.3"', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
|
|
if ResultCode = 0 then
|
|
begin
|
|
Result := true;
|
|
end;
|
|
end;
|
|
|
|
{ if dotnet is not installed then add it for download }
|
|
procedure CheckDotnetDependency;
|
|
begin
|
|
if not IsAspDotNetInstalled then
|
|
begin
|
|
AddDependency('aspdotnet80' + GetArchitectureSuffix + '.exe',
|
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
|
'ASP.NET Core Runtime 8.0.3' + GetArchitectureTitle,
|
|
GetString('https://download.visualstudio.microsoft.com/download/pr/6e92e2d6-32bb-4ff7-9424-78cd278076e8/7b23ff0e6bb04586ad90a0289b31d8d5/aspnetcore-runtime-8.0.3-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/e91876a9-1760-42cb-a6f4-97c57e9cca52/b433fcf4768929539f17e1908cb315bf/aspnetcore-runtime-8.0.3-win-x64.exe'),
|
|
'', False, False, False);
|
|
end;
|
|
|
|
if not IsDotNetDesktopInstalled then
|
|
begin
|
|
AddDependency('dotnet80desktop' + GetArchitectureSuffix + '.exe',
|
|
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
|
|
'.NET Desktop Runtime 8.0.3' + GetArchitectureTitle,
|
|
GetString('https://download.visualstudio.microsoft.com/download/pr/c629f243-5125-4751-a5ff-e78fa45646b1/85777e3e3f58f863d884fd4b8a1453f2/windowsdesktop-runtime-8.0.3-win-x86.exe', 'https://download.visualstudio.microsoft.com/download/pr/51bc18ac-0594-412d-bd63-18ece4c91ac4/90b47b97c3bfe40a833791b166697e67/windowsdesktop-runtime-8.0.3-win-x64.exe'),
|
|
'', False, False, False);
|
|
end;
|
|
end;
|