bastion 0.53.2
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
//go:build windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// hideConsole stops a child process from opening a console window.
|
||||
//
|
||||
// THE SYMPTOM: two flashing blue screens, seen again and again. Two, and
|
||||
// they flash, and they come back — that is the shape of this bug exactly.
|
||||
// Three Windows paths shell out to powershell.exe:
|
||||
//
|
||||
// schedulers_windows.go:44 Get-ScheduledTask (the scheduled-job inventory)
|
||||
// origin_windows.go:79 Win32_Service 'Schedule' (the scheduler's own pid)
|
||||
// computer_tree_windows.go:97 UIAutomation (on demand, not on the beat)
|
||||
//
|
||||
// The first two sit on the heartbeat path and are each cached for
|
||||
// schedCacheFor = 10 minutes (schedulers.go:435), so they expire together and
|
||||
// respawn together: TWO windows, every ten minutes, for ever. The third only
|
||||
// runs when the host asks to read the screen.
|
||||
//
|
||||
// WHY IT ONLY STARTED NOW, AND WHY IT IS 0.24.0's DOING. A console child
|
||||
// INHERITS its parent's console when the parent has one — started from a
|
||||
// terminal, these three were invisible for as long as they have existed. 0.24.0
|
||||
// added relaunchAfterUpdate, which restarts the bastion with DETACHED_PROCESS
|
||||
// (relaunch_windows.go:47) because Windows has no service to do it. A detached
|
||||
// process has NO console, so there is none to inherit, and Windows allocates a
|
||||
// fresh one for each child — which is a window, on screen, in front of whatever
|
||||
// the user was doing. The same commit that made the bastion survive an update
|
||||
// is what made its shell-outs visible.
|
||||
//
|
||||
// CREATE_NO_WINDOW is the correct flag for a child whose output we capture and
|
||||
// whose input we never supply: it still gets a console object, so PowerShell
|
||||
// runs normally, but no window is created for it. HideWindow alone would ask
|
||||
// the child politely to start minimised and PowerShell does not always honour
|
||||
// it. Both are set because they cost nothing together.
|
||||
//
|
||||
// Not applied to relaunchAfterUpdate: that one sets DETACHED_PROCESS already
|
||||
// and must keep it — it is the flag that lets the replacement outlive us.
|
||||
func hideConsole(cmd *exec.Cmd) {
|
||||
if cmd == nil {
|
||||
return
|
||||
}
|
||||
if cmd.SysProcAttr == nil {
|
||||
cmd.SysProcAttr = &windows.SysProcAttr{}
|
||||
}
|
||||
cmd.SysProcAttr.HideWindow = true
|
||||
cmd.SysProcAttr.CreationFlags |= windows.CREATE_NO_WINDOW
|
||||
}
|
||||
Reference in New Issue
Block a user