From 8ac02b3b35fef081da98f96c323ed98f42183438 Mon Sep 17 00:00:00 2001 From: jim800121chen Date: Mon, 9 Mar 2026 18:45:53 +0800 Subject: [PATCH] fix: Windows installer issues - Python detection and scheduled task - findPython3: skip Windows Store stub (WindowsApps), search common install locations (LocalAppData/Programs/Python/PythonXXX) - installAutoRestart: use schtasks instead of PowerShell Register-ScheduledTask to avoid XML parsing errors on non-English (Chinese) Windows Co-Authored-By: Claude Opus 4.6 --- edge-ai-platform/installer/app.go | 41 ++++++++++++++++--- .../installer/platform_windows.go | 23 ++++++----- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/edge-ai-platform/installer/app.go b/edge-ai-platform/installer/app.go index a3f7b44..4934b32 100644 --- a/edge-ai-platform/installer/app.go +++ b/edge-ai-platform/installer/app.go @@ -753,15 +753,46 @@ func (inst *Installer) runUninstall() { // findPython3 locates a Python 3 interpreter. func findPython3() (string, error) { - if p, err := exec.LookPath("python3"); err == nil { - return p, nil - } - if p, err := exec.LookPath("python"); err == nil { - out, _ := exec.Command(p, "--version").Output() + // Try python3 first, then python + for _, name := range []string{"python3", "python"} { + p, err := exec.LookPath(name) + if err != nil { + continue + } + // Skip Windows Store stub (WindowsApps) — it opens the Store instead of running Python + if runtime.GOOS == "windows" && strings.Contains(strings.ToLower(p), "windowsapps") { + continue + } + out, err := exec.Command(p, "--version").Output() + if err != nil { + continue // command exists but can't run (stub or broken) + } if strings.Contains(string(out), "Python 3") { return p, nil } } + + // On Windows, check common install locations + if runtime.GOOS == "windows" { + localAppData := os.Getenv("LOCALAPPDATA") + programFiles := os.Getenv("ProgramFiles") + for _, ver := range []string{"Python312", "Python313", "Python311", "Python310"} { + for _, base := range []string{ + filepath.Join(localAppData, "Programs", "Python", ver), + filepath.Join(programFiles, "Python"+ver[6:]), // e.g. ProgramFiles\Python312 -> Python12... skip + filepath.Join(programFiles, ver), + } { + p := filepath.Join(base, "python.exe") + if _, err := os.Stat(p); err == nil { + out, err := exec.Command(p, "--version").Output() + if err == nil && strings.Contains(string(out), "Python 3") { + return p, nil + } + } + } + } + } + return "", fmt.Errorf("python3 not found") } diff --git a/edge-ai-platform/installer/platform_windows.go b/edge-ai-platform/installer/platform_windows.go index e22b0aa..387ec1c 100644 --- a/edge-ai-platform/installer/platform_windows.go +++ b/edge-ai-platform/installer/platform_windows.go @@ -109,21 +109,22 @@ func installAutoRestart(installDir string) error { // Remove existing task if present exec.Command("schtasks", "/Delete", "/TN", taskName, "/F").Run() - // Create scheduled task that runs at logon and restarts on failure - // Using PowerShell for more control over restart settings - psScript := fmt.Sprintf(` -$Action = New-ScheduledTaskAction -Execute '%s' -Argument '--tray' -WorkingDirectory '%s' -$Trigger = New-ScheduledTaskTrigger -AtLogOn -$Settings = New-ScheduledTaskSettingsSet -RestartCount 3 -RestartInterval (New-TimeSpan -Seconds 5) -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -ExecutionTimeLimit (New-TimeSpan -Days 0) -Register-ScheduledTask -TaskName '%s' -Action $Action -Trigger $Trigger -Settings $Settings -Description 'Edge AI Platform Server' -Force -Start-ScheduledTask -TaskName '%s' -`, binPath, installDir, taskName, taskName) - - cmd := exec.Command("powershell", "-NoProfile", "-Command", psScript) + // Use schtasks instead of PowerShell Register-ScheduledTask + // to avoid XML parsing issues on non-English Windows + cmd := exec.Command("schtasks", "/Create", + "/TN", taskName, + "/TR", fmt.Sprintf(`"%s" --tray`, binPath), + "/SC", "ONLOGON", + "/RL", "HIGHEST", + "/F", + ) if out, err := cmd.CombinedOutput(); err != nil { return fmt.Errorf("scheduled task creation failed: %s — %w", string(out), err) } + // Start the task immediately + exec.Command("schtasks", "/Run", "/TN", taskName).Run() + return nil }