Detach managed processes from run console

This commit is contained in:
npc0-hue
2026-08-31 04:58:24 +08:00
parent f63f0966ff
commit 90de21ad9f
2 changed files with 15 additions and 9 deletions
+12 -6
View File
@@ -22,17 +22,23 @@ import (
"golang.org/x/sys/windows"
)
const managedProcessHelperFlag = "--run-managed-process-helper"
const (
managedProcessHelperFlag = "--run-managed-process-helper"
managedProcessDetachedFlags = windows.DETACHED_PROCESS | windows.CREATE_NEW_PROCESS_GROUP | windows.CREATE_BREAKAWAY_FROM_JOB
)
func configureManagedProcessCommand(cmd *exec.Cmd) {
// Run may itself be launched by a service or task scheduler job that
// terminates its process tree on shutdown. The helper is the durable
// owner of the game process, so ask Windows to keep it outside that job.
// The helper itself does not need a console: its stdout/stderr are already
// durable files. CREATE_NEW_CONSOLE creates a second hidden conhost in a
// non-interactive Task Scheduler session and prevents the child pseudo
// console from initializing on Windows Server.
cmd.SysProcAttr = &syscall.SysProcAttr{CreationFlags: windows.CREATE_NO_WINDOW | windows.CREATE_BREAKAWAY_FROM_JOB, HideWindow: true}
// durable files. Detaching also prevents an operator Ctrl+C used to restart
// Run from propagating into the helper, cmd wrapper, or game process whose
// logs the next Run instance must resume tailing.
// CREATE_NEW_CONSOLE creates a second hidden conhost in a non-interactive
// Task Scheduler session and prevents the child pseudo console from
// initializing on Windows Server.
cmd.SysProcAttr = &syscall.SysProcAttr{CreationFlags: managedProcessDetachedFlags, HideWindow: true}
}
// Windows console output is collected by a child helper that owns the
@@ -532,7 +538,7 @@ func runManagedShellWithPipes(command ProcessCommand, stopEventName string, stdo
}
startup := &windows.StartupInfo{Cb: uint32(unsafe.Sizeof(windows.StartupInfo{})), Flags: windows.STARTF_USESTDHANDLES | windows.STARTF_USESHOWWINDOW, ShowWindow: windows.SW_HIDE, StdInput: inputRead, StdOutput: stdoutWrite, StdErr: stderrWrite}
var processInfo windows.ProcessInformation
if err := windows.CreateProcess(applicationName, &commandLine[0], nil, nil, true, windows.CREATE_BREAKAWAY_FROM_JOB|windows.CREATE_NO_WINDOW|windows.CREATE_UNICODE_ENVIRONMENT, environment, workDir, startup, &processInfo); err != nil {
if err := windows.CreateProcess(applicationName, &commandLine[0], nil, nil, true, managedProcessDetachedFlags|windows.CREATE_UNICODE_ENVIRONMENT, environment, workDir, startup, &processInfo); err != nil {
closeOnError()
return 1, fmt.Errorf("start managed shell: %w", err)
}