Skip to main content
Glama
platform_windows.go2.86 kB
//go:build windows package process import ( "fmt" "os" "os/exec" "strconv" "strings" "syscall" "time" ) // setupProcessGroup sets up process group for Windows systems func setupProcessGroup(cmd *exec.Cmd) { // On Windows, we use CREATE_NEW_PROCESS_GROUP to allow proper termination if cmd.SysProcAttr == nil { cmd.SysProcAttr = &syscall.SysProcAttr{} } cmd.SysProcAttr.CreationFlags = syscall.CREATE_NEW_PROCESS_GROUP } // killProcessTree kills a process and all its children on Windows func killProcessTree(pid int) { // Use taskkill with /T flag to kill the process tree cmd := exec.Command("taskkill", "/F", "/T", "/PID", strconv.Itoa(pid)) _ = cmd.Run() // Ignore errors, process might already be dead // Give processes a moment to die time.Sleep(50 * time.Millisecond) // Double-check with direct kill if proc, err := os.FindProcess(pid); err == nil { _ = proc.Kill() // Ignore errors during forced cleanup } } // killProcessByPID kills a single process on Windows func killProcessByPID(pid int) { // First try taskkill for cleaner shutdown cmd := exec.Command("taskkill", "/F", "/PID", strconv.Itoa(pid)) _ = cmd.Run() // Ignore errors // Fallback to direct kill if proc, err := os.FindProcess(pid); err == nil { _ = proc.Kill() // Ignore errors during cleanup } } // ensureProcessDead makes sure a process is really dead on Windows func ensureProcessDead(pid int) { // Check if process exists using tasklist cmd := exec.Command("tasklist", "/FI", fmt.Sprintf("PID eq %d", pid)) output, err := cmd.Output() if err != nil { return // Process probably doesn't exist } // If the process is still in the output, kill it if strings.Contains(string(output), strconv.Itoa(pid)) { killProcessByPID(pid) } } // findProcessUsingPort finds the process ID using a specific port on Windows func findProcessUsingPort(port int) (int, error) { // Use netstat to find the process using the port cmd := exec.Command("netstat", "-ano", "-p", "tcp") output, err := cmd.Output() if err != nil { return 0, err } // Look for lines containing the port lines := strings.Split(string(output), "\n") portStr := fmt.Sprintf(":%d", port) for _, line := range lines { if strings.Contains(line, portStr) && strings.Contains(line, "LISTENING") { // Extract PID from the last column fields := strings.Fields(line) if len(fields) >= 5 { pid, err := strconv.Atoi(fields[len(fields)-1]) if err == nil && pid > 0 { return pid, nil } } } } return 0, fmt.Errorf("no process found using port %d", port) } // killProcessesByName kills all processes matching a name pattern on Windows func killProcessesByName(pattern string) { // Use taskkill with image name filter cmd := exec.Command("taskkill", "/F", "/IM", pattern+"*") _ = cmd.Run() // Ignore errors, processes might not exist }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/standardbeagle/brummer'

If you have feedback or need assistance with the MCP directory API, please join our Discord server