From 0e00f5dcd4fb5df1c93e1934ebc42ecb1e664a16 Mon Sep 17 00:00:00 2001 From: atavism Date: Wed, 25 Mar 2026 07:48:01 -0700 Subject: [PATCH 1/4] Fix Windows installer cleanup --- windows/packaging/exe/inno_setup.iss | 130 +++++++++++++++++++++++++-- 1 file changed, 125 insertions(+), 5 deletions(-) diff --git a/windows/packaging/exe/inno_setup.iss b/windows/packaging/exe/inno_setup.iss index 6540da7c1b..e2e7f68a03 100644 --- a/windows/packaging/exe/inno_setup.iss +++ b/windows/packaging/exe/inno_setup.iss @@ -269,6 +269,8 @@ ArchitecturesAllowed=x64 ArchitecturesInstallIn64BitMode=x64 SetupLogging=yes UninstallLogging=yes +CloseApplications=yes +RestartApplications=no [Languages] {% for locale in LOCALES %} @@ -291,10 +293,6 @@ Name: "{autoprograms}\\{{DISPLAY_NAME}}"; Filename: "{app}\\{{EXECUTABLE_NAME}}" Name: "{autodesktop}\\{{DISPLAY_NAME}}"; Filename: "{app}\\{{EXECUTABLE_NAME}}"; Tasks: desktopicon [Run] -; Stop/delete any existing service -Filename: "{sys}\sc.exe"; Parameters: "stop ""{#SvcName}"""; Flags: runhidden -Filename: "{sys}\sc.exe"; Parameters: "delete ""{#SvcName}"""; Flags: runhidden - ; Create service Filename: "{sys}\sc.exe"; \ Parameters: "create ""{#SvcName}"" binPath= ""{app}\lanternsvc.exe"" start= delayed-auto DisplayName= ""{#SvcDisplayName}"""; \ @@ -318,9 +316,131 @@ Filename: "{sys}\sc.exe"; Parameters: "delete ""{#SvcName}"""; Flags: runhidden Type: filesandordirs; Name: "{#ProgramDataDir}" [Code] +const + ServiceStopTimeoutMs = 20000; + ServicePollIntervalMs = 250; + UninstallRegSubKey = 'Software\Microsoft\Windows\CurrentVersion\Uninstall\{#SetupSetting("AppId")}_is1'; + +function ExtractExecutablePath(const CommandLine: String): String; +var + S: String; + EndQuote: Integer; + FirstSpace: Integer; +begin + S := Trim(CommandLine); + if S = '' then begin + Result := ''; + exit; + end; + + if S[1] = '"' then begin + Delete(S, 1, 1); + EndQuote := Pos('"', S); + if EndQuote > 0 then begin + Result := Copy(S, 1, EndQuote - 1); + end else begin + Result := S; + end; + exit; + end; + + FirstSpace := Pos(' ', S); + if FirstSpace > 0 then begin + Result := Copy(S, 1, FirstSpace - 1); + end else begin + Result := S; + end; +end; + +procedure RemoveStaleUninstallEntry(const RootKey: Integer; const RootName: String); +var + UninstallString: String; + UninstallExePath: String; +begin + if not RegQueryStringValue(RootKey, UninstallRegSubKey, 'UninstallString', UninstallString) then begin + exit; + end; + + UninstallExePath := ExtractExecutablePath(UninstallString); + if (UninstallExePath = '') or FileExists(UninstallExePath) then begin + exit; + end; + + Log( + Format( + 'Removing stale uninstall entry at %s\%s (missing uninstaller: %s)', + [RootName, UninstallRegSubKey, UninstallExePath] + ) + ); + if not RegDeleteKeyIncludingSubkeys(RootKey, UninstallRegSubKey) then begin + Log('Failed to remove stale uninstall entry'); + end; +end; + +function ExecSc(const Parameters: String; var ExitCode: Integer): Boolean; +begin + Result := Exec( + ExpandConstant('{sys}\sc.exe'), + Parameters, + '', + SW_HIDE, + ewWaitUntilTerminated, + ExitCode + ); + if Result then begin + Log(Format('sc.exe %s (exit=%d)', [Parameters, ExitCode])); + end else begin + Log(Format('failed to launch sc.exe %s (error=%d)', [Parameters, GetLastError])); + end; +end; + +procedure StopAndDeleteService; +var + ExitCode: Integer; +begin + ExecSc('stop "{#SvcName}"', ExitCode); + ExecSc('delete "{#SvcName}"', ExitCode); +end; + +function WaitForServiceDelete(const TimeoutMs: Integer): Boolean; +var + ExitCode: Integer; + ElapsedMs: Integer; +begin + ElapsedMs := 0; + while ElapsedMs <= TimeoutMs do begin + if ExecSc('query "{#SvcName}"', ExitCode) then begin + // SERVICE_DOES_NOT_EXIST + if ExitCode = 1060 then begin + Result := True; + exit; + end; + end; + Sleep(ServicePollIntervalMs); + ElapsedMs := ElapsedMs + ServicePollIntervalMs; + end; + Result := False; +end; + +procedure CurStepChanged(CurStep: TSetupStep); +begin + if CurStep <> ssInstall then begin + exit; + end; + + Log('Pre-install service cleanup started'); + StopAndDeleteService; + if not WaitForServiceDelete(ServiceStopTimeoutMs) then begin + Log('Timed out waiting for service deletion; continuing install'); + end; +end; + function InitializeSetup: Boolean; begin + RemoveStaleUninstallEntry(HKLM, 'HKLM'); + RemoveStaleUninstallEntry(HKCU, 'HKCU'); + Dependency_AddWebView2; Dependency_AddVC2015To2022; Result := True; -end; \ No newline at end of file +end; From 919deaebd3c91c5ca792871a6592421e3bdaf331 Mon Sep 17 00:00:00 2001 From: atavism Date: Wed, 25 Mar 2026 09:59:02 -0700 Subject: [PATCH 2/4] Fix Windows installer script syntax --- windows/packaging/exe/inno_setup.iss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/windows/packaging/exe/inno_setup.iss b/windows/packaging/exe/inno_setup.iss index e2e7f68a03..30548aa27a 100644 --- a/windows/packaging/exe/inno_setup.iss +++ b/windows/packaging/exe/inno_setup.iss @@ -368,7 +368,7 @@ begin Log( Format( - 'Removing stale uninstall entry at %s\%s (missing uninstaller: %s)', + 'Removing stale uninstall entry at root=%s key=%s (missing uninstaller: %s)', [RootName, UninstallRegSubKey, UninstallExePath] ) ); From bb7691365699aeed1c8df99581cb30fe64611cbc Mon Sep 17 00:00:00 2001 From: atavism Date: Wed, 25 Mar 2026 10:56:58 -0700 Subject: [PATCH 3/4] code review updates --- windows/packaging/exe/inno_setup.iss | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/windows/packaging/exe/inno_setup.iss b/windows/packaging/exe/inno_setup.iss index 30548aa27a..37427f2c8b 100644 --- a/windows/packaging/exe/inno_setup.iss +++ b/windows/packaging/exe/inno_setup.iss @@ -367,10 +367,9 @@ begin end; Log( - Format( - 'Removing stale uninstall entry at root=%s key=%s (missing uninstaller: %s)', - [RootName, UninstallRegSubKey, UninstallExePath] - ) + 'Removing stale uninstall entry at root=' + RootName + + ' key=' + UninstallRegSubKey + + ' (missing uninstaller: ' + UninstallExePath + ')' ); if not RegDeleteKeyIncludingSubkeys(RootKey, UninstallRegSubKey) then begin Log('Failed to remove stale uninstall entry'); @@ -388,9 +387,12 @@ begin ExitCode ); if Result then begin - Log(Format('sc.exe %s (exit=%d)', [Parameters, ExitCode])); + Log('sc.exe ' + Parameters + ' (exit=' + IntToStr(ExitCode) + ')'); end else begin - Log(Format('failed to launch sc.exe %s (error=%d)', [Parameters, GetLastError])); + Log( + 'failed to launch sc.exe ' + Parameters + + ' (error=' + IntToStr(GetLastError) + ')' + ); end; end; From 6574e0c4492c8794d0487db516de81d6fc1514af Mon Sep 17 00:00:00 2001 From: atavism Date: Wed, 25 Mar 2026 11:32:01 -0700 Subject: [PATCH 4/4] Fix Inno script compile error on ExecSc logging --- windows/packaging/exe/inno_setup.iss | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/windows/packaging/exe/inno_setup.iss b/windows/packaging/exe/inno_setup.iss index 37427f2c8b..9b9858c153 100644 --- a/windows/packaging/exe/inno_setup.iss +++ b/windows/packaging/exe/inno_setup.iss @@ -389,10 +389,7 @@ begin if Result then begin Log('sc.exe ' + Parameters + ' (exit=' + IntToStr(ExitCode) + ')'); end else begin - Log( - 'failed to launch sc.exe ' + Parameters + - ' (error=' + IntToStr(GetLastError) + ')' - ); + Log('failed to launch sc.exe ' + Parameters); end; end;