diff --git a/scripts/install_source.ps1 b/scripts/install_source.ps1 index 40a332bc0f..ad46b116a6 100644 --- a/scripts/install_source.ps1 +++ b/scripts/install_source.ps1 @@ -300,6 +300,34 @@ function Install-WindowsVCRedistIfNeeded { Write-Warning 'After installing, reopen PowerShell and restart OpenSquilla.' } +function Assert-OpenSquillaNotRunning { + if (-not $script:isWindowsHost) { + return + } + + try { + $running = @(Get-CimInstance Win32_Process -ErrorAction Stop | Where-Object { + $_.ProcessId -ne $PID -and + $_.CommandLine -and + $_.CommandLine -match '(?i)opensquilla' -and + $_.CommandLine -notmatch '(?i)install_source\.ps1' + }) + } catch { + Write-Warning 'install_source.ps1: could not inspect running processes; continuing with the installer.' + return + } + + if ($running.Count -eq 0) { + return + } + + $details = @($running | ForEach-Object { + $name = if ($_.Name) { $_.Name } else { 'unknown process' } + "$name (PID $($_.ProcessId))" + }) -join ', ' + Write-Error "install_source.ps1: OpenSquilla is running ($details). Stop it before upgrading so the existing CLI remains recoverable if installation cannot replace locked files." +} + # --- installer selection ---------------------------------------------------- $installer = $null @@ -454,6 +482,7 @@ if ($dryRun) { # --- execute --------------------------------------------------------------- +Assert-OpenSquillaNotRunning Test-SquillaRouterAssets Build-WebUI Install-WindowsVCRedistIfNeeded diff --git a/tests/test_install_scripts.py b/tests/test_install_scripts.py index d657a2b830..89929e370f 100644 --- a/tests/test_install_scripts.py +++ b/tests/test_install_scripts.py @@ -89,6 +89,16 @@ def test_windows_installer_stops_when_native_install_command_fails() -> None: assert "exit $installExitCode" in ps1 +def test_windows_source_installer_preflights_running_opensquilla() -> None: + ps1 = SOURCE_PS1.read_text(encoding="utf-8") + + assert "function Assert-OpenSquillaNotRunning" in ps1 + assert "Get-CimInstance Win32_Process" in ps1 + assert "install_source.ps1: OpenSquilla is running" in ps1 + assert "Stop it before upgrading" in ps1 + assert "Assert-OpenSquillaNotRunning" in ps1 + + def test_install_script_banners_are_ascii_for_windows_terminals() -> None: scripts = [ RELEASE_PS1.read_text(encoding="utf-8"),