igneum/packaging/windows/stop-igneum.ps1

52 lines
3 KiB
PowerShell

# Stops a running Igneum Miner on this PC. Run by the installer before an upgrade and on uninstall; also the Start Menu
# "Stop Igneum Miner" entry. 0.3.23 (7 October 2026, PC 2 at 20:54 BST: an installer quit the engine, the window host's
# restart ladder started the old engine again 10 s later, the host stayed locked and no file was replaced): the window
# host goes FIRST, by its path under the install folder, so nothing can restart the engine; then the engine is asked to
# quit through its local API (miners first, then the node), waited for, and whatever of ours is left is ended by path.
$ErrorActionPreference = 'Continue'
$install = Split-Path -Parent $MyInvocation.MyCommand.Path
function Ours { @(Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object { $_.ExecutablePath -and $_.ExecutablePath.StartsWith($install, [StringComparison]::OrdinalIgnoreCase) }) }
foreach ($h in (Ours | Where-Object { $_.Name -eq 'Igneum Miner.exe' })) {
Write-Host "ending the window host (pid $($h.ProcessId)) first, so it cannot start the engine again"
Stop-Process -Id $h.ProcessId -Force -ErrorAction SilentlyContinue
}
$urlFile = Join-Path $env:LOCALAPPDATA 'igneum\app\app.url'
$asked = $false
if (Test-Path $urlFile) {
$url = (Get-Content $urlFile -Raw).Trim()
if ($url) {
try {
Invoke-WebRequest -Uri ($url + 'api/quit') -Method POST -Body '{}' -ContentType 'application/json' -UseBasicParsing -TimeoutSec 5 | Out-Null
$asked = $true
Write-Host 'asked the engine to stop (miners first, then the node)'
} catch { }
}
}
if ($asked) {
$deadline = (Get-Date).AddSeconds(50)
while ((Get-Date) -lt $deadline) {
$alive = @(Ours | Where-Object { $_.Name -eq 'igneum-app.exe' -or $_.Name -eq 'igneumd.exe' })
if ($alive.Count -eq 0) { break }
Start-Sleep -Milliseconds 500
}
}
foreach ($p in (Ours)) {
Write-Host "ending $($p.Name) (pid $($p.ProcessId))"
Stop-Process -Id $p.ProcessId -Force -ErrorAction SilentlyContinue
}
# the files must be free before Inno copies: each exe opened for write, up to 30 s; one clear line for a file that stays locked
# (the installer's /CLOSEAPPLICATIONS is the fallback for that one)
$deadline = (Get-Date).AddSeconds(30)
$locked = @()
do {
$locked = @()
foreach ($n in @('Igneum Miner.exe', 'igneum-app.exe', 'igneumd.exe', 'igneum-miner.exe', 'igneum-worker-cuda.exe', 'igneum-worker-opencl.exe')) {
$f = Join-Path $install $n
if (-not (Test-Path $f)) { continue }
try { $fs = [IO.File]::Open($f, [IO.FileMode]::Open, [IO.FileAccess]::ReadWrite, [IO.FileShare]::None); $fs.Close() } catch { $locked += $n }
}
if ($locked.Count -eq 0) { break }
Start-Sleep -Milliseconds 500
} while ((Get-Date) -lt $deadline)
if ($locked.Count) { Write-Host ("STILL LOCKED after 30 s: " + ($locked -join ', ') + " (the installer's close-applications step is the fallback; a locked file is why an install leaves the old version in place)") } else { Write-Host 'every file of ours is free' }
Write-Host 'Igneum Miner is stopped.'