fix: improve Windows desktop application startup reliability

This commit fixes issue #526 where the Windows desktop app could not start reliably.
The changes improve Windows compatibility for:

1. Browser launching - Added PowerShell as a primary method for opening URLs
   with rundll32 as backup for better x86 architecture compatibility

2. Process termination - Implemented multi-tier Windows process killing with:
   - Primary: PowerShell CIM cmdlets (better for different architectures)
   - Fallback: Traditional WMI cmdlets
   - Last resort: Direct taskkill command

This should resolve startup issues on x86 Windows platforms.
This commit is contained in:
liugangjian 2026-03-05 11:07:32 +08:00
parent 4c2dfd5414
commit e9588148d7
2 changed files with 31 additions and 14 deletions

View file

@ -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()

View file

@ -117,7 +117,13 @@ func openBrowser(url string) error {
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: