//go:build windows package security import ( "os/exec" "strconv" "syscall" ) func prepareShellCmdSession(cmd *exec.Cmd) error { if cmd == nil { return nil } // 独立进程组,便于 taskkill /T 终止整棵子进程树。 if cmd.SysProcAttr == nil { cmd.SysProcAttr = &syscall.SysProcAttr{} } cmd.SysProcAttr.CreationFlags = syscall.CREATE_NEW_PROCESS_GROUP return nil } // terminateProcessGroup 使用 taskkill /F /T 终止进程及其子进程;rootPID 为 0 时回退到 cmd.Process.Pid。 func terminateProcessGroup(rootPID int, cmd *exec.Cmd) { pid := rootPID if pid <= 0 && cmd != nil && cmd.Process != nil { pid = cmd.Process.Pid } if pid <= 0 { return } tk := exec.Command("taskkill", "/F", "/T", "/PID", strconv.Itoa(pid)) if err := tk.Run(); err != nil { if cmd != nil && cmd.Process != nil { _ = cmd.Process.Kill() } } } // terminateCmdTree 使用 taskkill /F /T 终止进程及其子进程(Windows 上 Process.Kill 无法保证杀掉 python 等孙进程)。 func terminateCmdTree(cmd *exec.Cmd) { terminateProcessGroup(0, cmd) }