# Stop every MeshBay node on this machine before setup touches its files, or # before the uninstaller removes them. Embedded in the installer and run from # its plugins directory: the installed copy of anything may be the one being # replaced. # # 1. Ask the node through its own control API (/api/shutdown, loopback, per-run # token): the only stop that reaches a node in any session with no # elevation, and the one that lets it shut down properly -- WebRTC sessions # closed, transcodes stopped. # 2. Task Scheduler for a background-service node (the owner may end the task; # taskkill from here gets "Access is denied" in its session). # 3. taskkill for anything left in this session. # # Before all that, the command-line client (-InstallDir, setup's $INSTDIR): it # runs from the same node-runtime folder and holds its Python DLLs, so one left # open -- a `chat --follow`, a `stream` -- made the previous version's # uninstaller fail ("Failed to uninstall old application files"), silent # updates included. It is ended like the app is; only copies of this install. # Exit 0 once neither is left, 1 otherwise. param([string]$InstallDir = "") $ErrorActionPreference = "SilentlyContinue" if ($InstallDir) { $runtime = Join-Path $InstallDir "resources\node-runtime\" # Through CIM, not Get-Process: setup runs the 32-bit PowerShell ($SYSDIR is # SysWOW64 there), which reads no path for a 64-bit process -- the filter # matched nothing and the update failed as before. function CliLeft { @(Get-CimInstance Win32_Process -Filter "Name='meshbay-cli.exe'" ` -ErrorAction SilentlyContinue | Where-Object { $_.ExecutablePath -and $_.ExecutablePath.StartsWith($runtime, [StringComparison]::OrdinalIgnoreCase) }) } CliLeft | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue } $deadline = (Get-Date).AddSeconds(10) while ((CliLeft).Count -and (Get-Date) -lt $deadline) { Start-Sleep -Milliseconds 250 } if ((CliLeft).Count) { exit 1 } } function NodeLeft { [bool](Get-Process -Name meshbay-node -ErrorAction SilentlyContinue) } function WaitGone([int]$Seconds) { $deadline = (Get-Date).AddSeconds($Seconds) while ((NodeLeft) -and (Get-Date) -lt $deadline) { Start-Sleep -Milliseconds 250 } -not (NodeLeft) } if (-not (NodeLeft)) { exit 0 } $cfg = Join-Path $env:LOCALAPPDATA "meshbay" $port = 18000 $toml = Join-Path $cfg "node.toml" if (Test-Path $toml) { $m = Select-String -Path $toml -Pattern '^\s*ui_port\s*=\s*(\d+)' | Select-Object -First 1 if ($m) { $port = [int]$m.Matches[0].Groups[1].Value } } $tokenFile = Join-Path $cfg "data\ui-token" if (Test-Path $tokenFile) { $token = (Get-Content $tokenFile -Raw).Trim() try { Invoke-WebRequest -UseBasicParsing -Method Post -TimeoutSec 5 ` -Uri "http://127.0.0.1:$port/api/shutdown?t=$token" | Out-Null if (WaitGone 20) { exit 0 } } catch { } } & schtasks /end /tn "MeshBay Node" 2>&1 | Out-Null Get-Process -Name meshbay-node -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue if (WaitGone 20) { exit 0 } exit 1