Kill only this run's browser on the remote host

Both shutdown paths ran Get-Process chrome,msedge | Stop-Process -Force,
which is every browser on the machine. The remote host is somebody's
desktop: a test run must not close the windows they are working in. It
only stayed harmless because the test account cannot touch another
user's processes.

The launcher now writes its browser pid to %TEMP%\gm-browser-<port>.pid
and kills that pid; the job object still takes the renderer children.

Measured against the Windows desktop: five msedge processes belonging to
the logged-in user before the run, five after, and our chrome gone.
24 smoke checks ALL PASSED.
This commit is contained in:
root committed 2026-09-09 09:24:51 +02:00
1 parent dd2ea8c761
commit 1bd6e89ff5
2 files changed
+13 -5

No files matched your search

+4 -2
View File
@@ -103,16 +103,18 @@ export function launchBrowser({ port, width, height }) {
/**
* The launcher notices a finished run on its own, but only after its idle window – a browser
* lingering a minute on someone else's desktop is rude, so end it now and let that window be
* the net for runs that die without reaching here.
* the net for runs that die without reaching here. Only this run's pid: the host is somebody's
* desktop, and killing by name would close the browser they are reading this in.
*/
stop: () => {
const pidFile = `$env:TEMP\\gm-browser-${port}.pid`;
try {
execFileSync(
'ssh',
[
...sshArgs(key),
remote,
'powershell -NoProfile -Command "Get-Process chrome,msedge -ErrorAction SilentlyContinue | Stop-Process -Force"',
`powershell -NoProfile -Command "if (Test-Path ${pidFile}) { Stop-Process -Id (Get-Content ${pidFile}) -Force -ErrorAction SilentlyContinue }"`,
],
{ stdio: 'pipe', timeout: 20_000 },
);
+9 -3
View File
@@ -73,6 +73,10 @@ $flags = @(
$job = [GmJob]::Create()
$proc = Start-Process -FilePath $exe -ArgumentList $flags -PassThru -NoNewWindow
[GmJob]::Assign($job, $proc.Handle)
# The pid file is how the caller ends this run's browser without touching the browser windows the
# person at this desk has open.
$pidFile = Join-Path $env:TEMP "gm-browser-$Port.pid"
Set-Content -Path $pidFile -Value $proc.Id
[Console]::Error.WriteLine("gm-browser: $exe pid=$($proc.Id) port=$Port job=on")
# Either the browser dies on its own, or nobody is driving it any more. Both must end this script.
@@ -107,8 +111,10 @@ while (-not $proc.HasExited) {
if ($proc.HasExited) {
[Console]::Error.WriteLine("gm-browser: $reason $($proc.ExitCode)")
} else {
# taskkill and tasklist filters are denied to this account; Stop-Process is not. The job object
# would do it anyway when this process ends - this just makes the kill immediate.
Get-Process chrome, msedge -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
# By pid, never by name: this host is somebody's desktop and their own Chrome must survive a test
# run. taskkill is denied to this account, Stop-Process is not, and the job object takes the
# renderer children when this process ends - this just makes the kill immediate.
Stop-Process -Id $proc.Id -Force -ErrorAction SilentlyContinue
[Console]::Error.WriteLine("gm-browser: $reason, killed the browser")
}
Remove-Item $pidFile -Force -ErrorAction SilentlyContinue