diff --git a/edge-ai-platform/installer/platform_windows.go b/edge-ai-platform/installer/platform_windows.go index 18b7a48..862e23e 100644 --- a/edge-ai-platform/installer/platform_windows.go +++ b/edge-ai-platform/installer/platform_windows.go @@ -169,46 +169,71 @@ func installUSBDriver(installDir string) error { // installKneronDriverViaSDK uses the KneronPLUS SDK's built-in libwdi to // install WinUSB driver for all known Kneron devices. Must be called after // the Python venv with kp module is set up. +// libwdi requires admin privileges, so this runs elevated via UAC. func installKneronDriverViaSDK(installDir string) error { venvPython := filepath.Join(installDir, "venv", "Scripts", "python.exe") if _, err := os.Stat(venvPython); err != nil { return fmt.Errorf("Python venv not found, cannot install driver") } - // Use kp.core.install_driver_for_windows() for each known product ID - // KL520=0x100, KL720=0x720, KL720_LEGACY=0x200 - script := ` -import sys + resultPath := filepath.Join(os.TempDir(), "edge-ai-driver-result.txt") + os.Remove(resultPath) + + // Python script that installs WinUSB driver for all Kneron devices + pyScript := fmt.Sprintf(` +import sys, os +result_path = r'%s' try: + # Ensure kp can find its DLLs + kp_lib = os.path.join(r'%s', 'venv', 'Lib', 'site-packages', 'kp', 'lib') + if os.path.isdir(kp_lib): + os.environ['PATH'] = kp_lib + ';' + os.environ.get('PATH', '') + os.add_dll_directory(kp_lib) import kp + results = [] for pid in [kp.ProductId.KP_DEVICE_KL520, kp.ProductId.KP_DEVICE_KL720, kp.ProductId.KP_DEVICE_KL720_LEGACY]: try: kp.core.install_driver_for_windows(pid) - print(f"OK: driver installed for {pid.name}") + results.append(f"OK: {pid.name}") except Exception as e: - print(f"SKIP: {pid.name}: {e}") - print("DONE") -except ImportError: - print("ERROR: kp module not available") - sys.exit(1) -` - cmd := exec.Command(venvPython, "-c", script) - cmd.Dir = installDir - // Ensure kp can find its DLLs - cmd.Env = append(os.Environ(), - fmt.Sprintf("PATH=%s;%s;%s", - filepath.Join(installDir, "venv", "Lib", "site-packages", "kp", "lib"), - installDir, - os.Getenv("PATH"))) + results.append(f"SKIP: {pid.name}: {e}") + with open(result_path, 'w') as f: + f.write('\n'.join(results) + '\nDONE\n') +except ImportError as e: + with open(result_path, 'w') as f: + f.write(f'ERROR: kp module not available: {e}\n') +except Exception as e: + with open(result_path, 'w') as f: + f.write(f'ERROR: {e}\n') +`, resultPath, installDir) - out, err := cmd.CombinedOutput() - if err != nil { - return fmt.Errorf("WinUSB driver install via KneronPLUS SDK failed: %s — please install manually using Zadig (https://zadig.akeo.ie/)", strings.TrimSpace(string(out))) + // Write Python script to temp file + scriptPath := filepath.Join(os.TempDir(), "edge-ai-install-usb-driver.py") + if err := os.WriteFile(scriptPath, []byte(pyScript), 0644); err != nil { + return fmt.Errorf("failed to write driver install script: %w", err) + } + defer os.Remove(scriptPath) + + // Run elevated via UAC (libwdi requires admin) + elevateCmd := fmt.Sprintf( + `Start-Process -FilePath '%s' -ArgumentList '"%s"' -Verb RunAs -Wait -WindowStyle Hidden`, + venvPython, scriptPath, + ) + cmd := exec.Command("powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", elevateCmd) + if out, err := cmd.CombinedOutput(); err != nil { + return fmt.Errorf("WinUSB driver install requires administrator permission — please install manually using Zadig (https://zadig.akeo.ie/). Details: %s", strings.TrimSpace(string(out))) } - output := string(out) - if strings.Contains(output, "ERROR:") { - return fmt.Errorf("WinUSB driver install failed: %s — please install manually using Zadig (https://zadig.akeo.ie/)", strings.TrimSpace(output)) + // Read result + resultData, err := os.ReadFile(resultPath) + os.Remove(resultPath) + if err != nil { + return fmt.Errorf("WinUSB driver install completed but could not read result — please verify in Device Manager or install manually using Zadig (https://zadig.akeo.ie/)") + } + + result := strings.TrimSpace(string(resultData)) + if strings.Contains(result, "ERROR:") { + return fmt.Errorf("WinUSB driver install failed: %s — please install manually using Zadig (https://zadig.akeo.ie/)", result) } return nil