diff --git a/cmd/picoclaw-launcher/internal/server/process.go b/cmd/picoclaw-launcher/internal/server/process.go index bc2129bf5..ecd6229f3 100644 --- a/cmd/picoclaw-launcher/internal/server/process.go +++ b/cmd/picoclaw-launcher/internal/server/process.go @@ -106,10 +106,21 @@ func scanPipe(r io.Reader, buf *LogBuffer) { func handleStopGateway(w http.ResponseWriter, r *http.Request) { var err error if runtime.GOOS == "windows" { - // Kill via taskkill finding picoclaw.exe (though it might kill this config tool if it's named picoclaw-launcher.exe...? No, /IM does exact match usually, but just to be safe let's stop exactly picoclaw.exe) - // Alternatively, we use powershell to kill processes with commandline containing 'gateway' - psCmd := `Get-WmiObject Win32_Process | Where-Object { $_.CommandLine -match 'picoclaw.*gateway' } | ForEach-Object { Stop-Process $_.ProcessId -Force }` - err = exec.Command("powershell", "-Command", psCmd).Run() + // Improved Windows process termination with multiple fallback methods + // Use PowerShell CIM cmdlet (most compatible with different Windows architectures) + psCmd := `Get-CimInstance Win32_Process | Where-Object { $_.Name -like 'picoclaw*.exe' -and $_.CommandLine -like '*gateway*' } | ForEach-Object { Stop-Process $_.ProcessId -Force }` + err = exec.Command("powershell", "-NoProfile", "-Command", psCmd).Run() + // If CIM fails on older systems, try traditional WMI approach + if err != nil { + log.Printf("Warning: CIM-based process termination failed: %v, trying WMI approach...\n", err) + psWithWmi := `Get-WmiObject Win32_Process | Where-Object { $_.CommandLine -match 'picoclaw.*gateway' } | ForEach-Object { Stop-Process $_.ProcessId -Force }` + err = exec.Command("powershell", "-NoProfile", "-Command", psWithWmi).Run() + // If all PowerShell methods fail, use direct taskkill as last resort + if err != nil { + log.Printf("Warning: PowerShell approaches failed: %v, using taskkill as final fallback...\n", err) + err = exec.Command("taskkill", "/F", "/IM", "picoclaw.exe").Run() + } + } } else { // Linux/macOS err = exec.Command("pkill", "-f", "picoclaw gateway").Run() diff --git a/cmd/picoclaw-launcher/main.go b/cmd/picoclaw-launcher/main.go index 3323c31a8..79ea3f7ca 100644 --- a/cmd/picoclaw-launcher/main.go +++ b/cmd/picoclaw-launcher/main.go @@ -112,16 +112,22 @@ func main() { // openBrowser automatically opens the given URL in the default browser. func openBrowser(url string) error { - var err error - switch runtime.GOOS { - case "linux": - err = exec.Command("xdg-open", url).Start() +var err error +switch runtime.GOOS { +case "linux": +err = exec.Command("xdg-open", url).Start() case "windows": + // Using PowerShell approach which is more reliable on various Windows architectures (including x86) + err = exec.Command("powershell", "-NoProfile", "-Command", "Start-Process", url).Run() + // Fallback to rundll32 if PowerShell fails (ensuring compatibility with older/limited Windows systems) + if err != nil { + log.Printf("Warning: PowerShell failed to open browser: %v, trying rundll32...\n", err) err = exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start() - case "darwin": - err = exec.Command("open", url).Start() - default: - err = fmt.Errorf("unsupported platform") - } - return err + } +case "darwin": +err = exec.Command("open", url).Start() +default: +err = fmt.Errorf("unsupported platform") +} +return err }