The relaunch after an update called hideConsole on the command that
starts the new build. That sets SysProcAttr{HideWindow: true}, which on
Windows becomes SW_HIDE in the STARTUPINFO handed to CreateProcess — and
Windows applies it to the first top-level window the new process shows.
So the updated OpsLog started correctly, took the single-instance mutex,
opened the logbook and connected the rig, and never appeared.
That is the report, in full: a process in the task manager, no window,
no autostart programs, and ending it then launching OpsLog by hand
working every time. Two operators, both on 0.27.23.
Why 0.27.19 did not fix it: that commit fixed the other half of the same
symptom — the new instance being less patient than the old one is slow —
which was real and is still fixed. The window was never part of it.
Where it came from: removing the PowerShell helper. Start-Process
launched the exe with a normal show; the direct exec.Command that
replaced it borrowed hideConsole from the console tools next to it,
where hiding a console window is exactly right and where the three
remaining callers (tasklist, taskkill, the deferred-swap PowerShell)
still belong.
The proof it was this and not the waiting: OpsLog relaunches itself in
two places, and RestartApp — the database switch — was byte-identical
except that it never called hideConsole. It has never been reported
broken. Both now go through relaunchCmd, so the rule lives in one place
with the reason written down, rather than in two call sites that differed
by one line.
Two tests: relaunchCmd leaves SysProcAttr nil, and update.go does not
call hideConsole at all.
38 lines
1.6 KiB
Go
38 lines
1.6 KiB
Go
package main
|
|
|
|
import (
|
|
"os/exec"
|
|
"path/filepath"
|
|
)
|
|
|
|
// relaunchCmd builds the command that starts OpsLog again — after an update, or
|
|
// after a database switch.
|
|
//
|
|
// It exists to hold one fact in one place: a relaunch of OPSLOG ITSELF must not
|
|
// suppress the new process's window.
|
|
//
|
|
// The auto-update relaunch used to go through hideConsole, which sets
|
|
// SysProcAttr{HideWindow: true}. On Windows that puts SW_HIDE into the
|
|
// STARTUPINFO handed to CreateProcess, and Windows applies it to the first
|
|
// top-level window the new process shows. So the updated OpsLog started
|
|
// perfectly, took the single-instance mutex, connected the rig — and never
|
|
// became visible. Reported by two operators on 0.27.23 as "it goes to reload
|
|
// and just fails to load": a process in the task manager, no window, killing it
|
|
// and starting it by hand working every time.
|
|
//
|
|
// It arrived with the removal of the PowerShell helper. PowerShell's
|
|
// Start-Process launched the exe with a normal show, and the direct
|
|
// exec.Command that replaced it borrowed hideConsole from the console tools
|
|
// beside it — where hiding a console window is exactly right, and where every
|
|
// other caller still belongs. Two self-relaunches then differed by that one
|
|
// line, and only the hidden one was ever reported broken.
|
|
//
|
|
// So: no SysProcAttr at all, which is what RestartApp already did and why the
|
|
// database-switch relaunch never showed the fault. There is no console to
|
|
// suppress either way — OpsLog is linked for the Windows GUI subsystem.
|
|
func relaunchCmd(exe string, args ...string) *exec.Cmd {
|
|
cmd := exec.Command(exe, args...)
|
|
cmd.Dir = filepath.Dir(exe)
|
|
return cmd
|
|
}
|