//go:build windows package core import ( "bufio" "fmt" "io" "os/exec" "regexp" "strconv" "strings" "syscall" ) var ansiEscape = regexp.MustCompile(`\x1b\[[0-9;]*m`) // procAttr returns platform-specific process attributes. // On Windows, hides the console window. func procAttr() *syscall.SysProcAttr { return &syscall.SysProcAttr{ HideWindow: true, CreationFlags: 0x08000000, // CREATE_NO_WINDOW } } // killProcessByName kills all processes with the given name. func killProcessByName(name string, onKill func(pid int)) { // Use tasklist to find processes out, err := exec.Command("tasklist", "/FI", fmt.Sprintf("IMAGENAME eq %s.exe", name), "/FO", "CSV", "/NH").Output() if err != nil { return } for _, line := range strings.Split(string(out), "\n") { line = strings.TrimSpace(line) if line == "" || strings.Contains(line, "No tasks") { continue } // CSV format: "name.exe","PID","Session Name","Session#","Mem Usage" parts := strings.Split(line, ",") if len(parts) < 2 { continue } pidStr := strings.Trim(parts[1], "\" ") pid, err := strconv.Atoi(pidStr) if err != nil { continue } if onKill != nil { onKill(pid) } _ = exec.Command("taskkill", "/F", "/T", "/PID", pidStr).Run() } } // scanPipe reads lines from a pipe and calls handler for each. // ANSI escape codes are stripped before passing to handler. func scanPipe(r io.Reader, handler func(string)) { if r == nil { return } scanner := bufio.NewScanner(r) for scanner.Scan() { line := ansiEscape.ReplaceAllString(scanner.Text(), "") if line != "" { handler(line) } } }