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 <noreply@anthropic.com>
This commit is contained in:
jim800121chen 2026-03-09 18:45:53 +08:00
parent 9110e1647d
commit 8ac02b3b35
2 changed files with 48 additions and 16 deletions

View File

@ -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")
}

View File

@ -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
}