You've already forked agentic-coding-workflow
启动项目逻辑
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
//go:build windows
|
||||
|
||||
package proc
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os/exec"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// windowsGroup 用 Job Object 实现整树终止:把进程纳入一个设置了
|
||||
// KILL_ON_JOB_CLOSE 的 Job,此后该进程派生的所有子孙自动归入同一 Job,
|
||||
// 关闭 Job 句柄即整树终止。优于 Process.Kill(只杀单 PID,漏 node 等子进程)。
|
||||
type windowsGroup struct {
|
||||
job windows.Handle
|
||||
}
|
||||
|
||||
func newGroup() Group { return &windowsGroup{} }
|
||||
|
||||
// Prepare 在 Windows 为 no-op:Job 须在进程 Start 之后才能 Assign。
|
||||
func (g *windowsGroup) Prepare(cmd *exec.Cmd) {}
|
||||
|
||||
// Adopt 必须在 cmd.Start() 之后、子进程派生之前调用。竞态窗口:父进程 exec 后
|
||||
// 到首个子进程派生之间存在微秒级窗口(Go 无 pre-exec hook 无法完全消除),
|
||||
// 实践风险极小,文档化为已知限制。
|
||||
func (g *windowsGroup) Adopt(cmd *exec.Cmd) error {
|
||||
if cmd.Process == nil {
|
||||
return errors.New("proc: Adopt before Start")
|
||||
}
|
||||
job, err := windows.CreateJobObject(nil, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var info windows.JOBOBJECT_EXTENDED_LIMIT_INFORMATION
|
||||
info.BasicLimitInformation.LimitFlags = windows.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
|
||||
if _, err := windows.SetInformationJobObject(
|
||||
job,
|
||||
windows.JobObjectExtendedLimitInformation,
|
||||
uintptr(unsafe.Pointer(&info)),
|
||||
uint32(unsafe.Sizeof(info)),
|
||||
); err != nil {
|
||||
_ = windows.CloseHandle(job)
|
||||
return err
|
||||
}
|
||||
h, err := windows.OpenProcess(windows.PROCESS_SET_QUOTA|windows.PROCESS_TERMINATE, false, uint32(cmd.Process.Pid))
|
||||
if err != nil {
|
||||
_ = windows.CloseHandle(job)
|
||||
return err
|
||||
}
|
||||
defer windows.CloseHandle(h)
|
||||
if err := windows.AssignProcessToJobObject(job, h); err != nil {
|
||||
_ = windows.CloseHandle(job)
|
||||
return err
|
||||
}
|
||||
g.job = job
|
||||
return nil
|
||||
}
|
||||
|
||||
// TerminateGroup 在 Windows 无可靠 SIGTERM 等价物,直接关闭 Job 句柄触发
|
||||
// KILL_ON_JOB_CLOSE 整树终止(grace/done 不参与,仅保持接口签名一致)。
|
||||
func (g *windowsGroup) TerminateGroup(_ <-chan struct{}, _ time.Duration) {
|
||||
g.Close()
|
||||
}
|
||||
|
||||
func (g *windowsGroup) Close() {
|
||||
if g.job != 0 {
|
||||
_ = windows.CloseHandle(g.job)
|
||||
g.job = 0
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user