$ErrorActionPreference = 'Stop' $root = Split-Path $PSScriptRoot try { if (Get-Process 'KSwitcher.Screenshot' -ErrorAction SilentlyContinue | Where-Object { $_.Path -eq (Join-Path $root 'build\KSwitcher.Screenshot.exe') }) { throw 'Close screenshot editors before updating the development build.' } $exe = Join-Path $root 'build\KSwitcher.exe' $running = @(Get-Process KSwitcher -ErrorAction SilentlyContinue | Where-Object { $_.Path -eq $exe }) $stop = Start-Process -FilePath $exe -ArgumentList '--exit' -WindowStyle Hidden -PassThru if (-not $stop.WaitForExit(5000)) { throw 'Exit command timed out.' } foreach ($process in $running) { if (-not $process.WaitForExit(10000)) { throw 'KSwitcher did not stop.' } } $config = @(Get-Process 'KSwitcher.Config' -ErrorAction SilentlyContinue | Where-Object { $_.Path -eq (Join-Path $root 'build\KSwitcher.Config.exe') }) foreach ($process in $config) { if (-not $process.WaitForExit(10000)) { throw 'Close the configurator before updating.' } } Copy-Item -LiteralPath (Join-Path $root 'build\staged\KSwitcher.Config.exe') -Destination (Join-Path $root 'build\KSwitcher.Config.exe') -Force Copy-Item -LiteralPath (Join-Path $root 'build\staged\KSwitcher.exe') -Destination $exe -Force Copy-Item -LiteralPath (Join-Path $root 'build\staged\KSwitcher.Screenshot.exe') -Destination (Join-Path $root 'build\KSwitcher.Screenshot.exe') -Force $eventName = 'Local\KSwitcher.Update.Started.' + [guid]::NewGuid().ToString('N') $started = [System.Threading.EventWaitHandle]::new($false, [System.Threading.EventResetMode]::ManualReset, $eventName) try { $newProcess = Start-Process -FilePath $exe -ArgumentList "--update-ready-event=$eventName" -WorkingDirectory (Split-Path $exe) -WindowStyle Hidden -PassThru if (-not $started.WaitOne(10000)) { throw 'KSwitcher did not confirm startup within 10 seconds.' } if ($newProcess.WaitForExit(1000)) { throw "KSwitcher exited after startup (code $($newProcess.ExitCode))." } } finally { $started.Dispose() } 'OK' | Set-Content -LiteralPath (Join-Path $root 'build\update-result.txt') } catch { $_.Exception.Message | Set-Content -LiteralPath (Join-Path $root 'build\update-result.txt'); exit 1 }