From c8e628c6ca8f807abfe18440107c488657182c45 Mon Sep 17 00:00:00 2001 From: jim800121chen Date: Mon, 9 Mar 2026 21:01:59 +0800 Subject: [PATCH] fix: tray icon, console window, and device detection on Windows Tray icon: - Embed proper ICO files (green=running, red=stopped) instead of generic IDI_APPLICATION icon - Switch icon dynamically based on server state Console window: - FreeConsole() to fully detach from parent console - CREATE_NO_WINDOW flag on child server process to prevent black console window from appearing Device detection: - ResolvePython: add Windows venv paths (Scripts/python.exe) and %LOCALAPPDATA%\EdgeAIPlatform\venv, fallback to exec.LookPath - DetectDevices + startPython: prepend install dir to PATH so libusb-1.0.dll is found by pyusb/kp SDK - Also hide "cmd /c start" console when opening browser Co-Authored-By: Claude Opus 4.6 --- .../server/internal/driver/kneron/detector.go | 40 +++++- .../internal/driver/kneron/kl720_driver.go | 8 ++ .../server/tray/assets/icon_running.ico | Bin 0 -> 1118 bytes .../server/tray/assets/icon_stopped.ico | Bin 0 -> 1118 bytes edge-ai-platform/server/tray/webgui.go | 114 +++++++++++------- 5 files changed, 114 insertions(+), 48 deletions(-) create mode 100644 edge-ai-platform/server/tray/assets/icon_running.ico create mode 100644 edge-ai-platform/server/tray/assets/icon_stopped.ico diff --git a/edge-ai-platform/server/internal/driver/kneron/detector.go b/edge-ai-platform/server/internal/driver/kneron/detector.go index 69103bc..c7057be 100644 --- a/edge-ai-platform/server/internal/driver/kneron/detector.go +++ b/edge-ai-platform/server/internal/driver/kneron/detector.go @@ -13,17 +13,32 @@ import ( ) // ResolvePython finds the best Python interpreter for the given script path. -// Search order: script-local venv → parent venv → ~/.edge-ai-platform/venv → system python3. +// Search order: script-local venv → parent venv → platform config dir venv → system python3/python. func ResolvePython(scriptPath string) string { scriptDir := filepath.Dir(scriptPath) + parentDir := filepath.Dir(scriptDir) - candidates := []string{ - filepath.Join(scriptDir, "venv", "bin", "python3"), - filepath.Join(filepath.Dir(scriptDir), "venv", "bin", "python3"), + // Build candidate list with both Unix and Windows venv layouts + var candidates []string + for _, base := range []string{scriptDir, parentDir} { + candidates = append(candidates, + filepath.Join(base, "venv", "bin", "python3"), // Unix + filepath.Join(base, "venv", "Scripts", "python.exe"), // Windows + ) } if home, err := os.UserHomeDir(); err == nil { - candidates = append(candidates, filepath.Join(home, ".edge-ai-platform", "venv", "bin", "python3")) + candidates = append(candidates, + filepath.Join(home, ".edge-ai-platform", "venv", "bin", "python3"), + filepath.Join(home, ".edge-ai-platform", "venv", "Scripts", "python.exe"), + ) + } + + // On Windows, also check %LOCALAPPDATA%\EdgeAIPlatform\venv + if appData := os.Getenv("LOCALAPPDATA"); appData != "" { + candidates = append(candidates, + filepath.Join(appData, "EdgeAIPlatform", "venv", "Scripts", "python.exe"), + ) } for _, p := range candidates { @@ -32,6 +47,13 @@ func ResolvePython(scriptPath string) string { } } + // Fallback to system python + for _, name := range []string{"python3", "python"} { + if p, err := exec.LookPath(name); err == nil { + return p + } + } + return "python3" } @@ -70,6 +92,14 @@ func DetectDevices(scriptPath string) []driver.DeviceInfo { cmd := exec.Command(pythonBin, scriptPath) cmd.Stdin = nil + // Ensure libusb-1.0.dll can be found on Windows by adding the binary's + // directory to PATH (the installer places the DLL there). + scriptDir := filepath.Dir(scriptPath) + installDir := filepath.Dir(scriptDir) + cmd.Env = append(os.Environ(), + fmt.Sprintf("PATH=%s;%s;%s", installDir, scriptDir, os.Getenv("PATH")), + ) + stdinPipe, err := cmd.StdinPipe() if err != nil { return nil diff --git a/edge-ai-platform/server/internal/driver/kneron/kl720_driver.go b/edge-ai-platform/server/internal/driver/kneron/kl720_driver.go index 1442315..f8d079c 100644 --- a/edge-ai-platform/server/internal/driver/kneron/kl720_driver.go +++ b/edge-ai-platform/server/internal/driver/kneron/kl720_driver.go @@ -113,6 +113,14 @@ func (d *KneronDriver) startPython() error { } } + // On Windows, ensure libusb-1.0.dll can be found by adding the install + // directory to PATH (installer places the DLL there). + if runtime.GOOS == "windows" { + installDir := filepath.Dir(scriptDir) + cmd.Env = append(cmd.Env, + fmt.Sprintf("PATH=%s;%s;%s", installDir, scriptDir, os.Getenv("PATH"))) + } + stdinPipe, err := cmd.StdinPipe() if err != nil { return fmt.Errorf("failed to create stdin pipe: %w", err) diff --git a/edge-ai-platform/server/tray/assets/icon_running.ico b/edge-ai-platform/server/tray/assets/icon_running.ico new file mode 100644 index 0000000000000000000000000000000000000000..1f6ac7ce22845990a9bb4b34d28f9b7677f550f5 GIT binary patch literal 1118 zcmdUsK@LDb3`M`h0cK@w=_nR+5;t%|S8y7BqfI8A!9*+|RocAYuLCr^Lja#W#un%R z3=Ec7IqFR4+55{iEr^U+Bi8y>Ze`wFNbOQbSIv@#FmWmnd} y%d_|J0x#!vH`n@^fAK^9@&1&r@lc#?`=AHWDEW}uC2Jaq7daD&YA)6I!ut+2IOZb& literal 0 HcmV?d00001 diff --git a/edge-ai-platform/server/tray/assets/icon_stopped.ico b/edge-ai-platform/server/tray/assets/icon_stopped.ico new file mode 100644 index 0000000000000000000000000000000000000000..c5189e3de5f20420088ac3b8279e908deee8abfd GIT binary patch literal 1118 zcmdUsu?>JQ3= len(old) && s[:len(old)] == old { return new + s[len(old):] @@ -424,7 +453,6 @@ func replacePrefix(s, old, new string) string { return s } -// indexOf returns the index of substr in s, or -1 if not found. func indexOf(s, substr string) int { for i := 0; i <= len(s)-len(substr); i++ { if s[i:i+len(substr)] == substr {