feat: install WinUSB driver via KneronPLUS SDK (libwdi)
The KneronPLUS wheel bundles libwdi.dll and provides kp.core.install_driver_for_windows() which handles WinUSB driver installation internally. This replaces the unreliable pnputil + self-signed INF approach that failed due to unsigned INF rejection. Changes: - Split USB setup into two steps: "Setting up USB library" (extract libusb DLL + driver files) and "Installing USB device driver" (runs after Python/kp are installed) - New installKneronDriverViaSDK() calls kp SDK to install WinUSB for KL520, KL720, and KL720_LEGACY product IDs - Driver files still extracted as manual Zadig fallback - macOS/Linux: installUSBDriver() is a no-op Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5e7edea08b
commit
86b168c78a
@ -230,8 +230,9 @@ func (inst *Installer) runInstall(config InstallConfig) {
|
||||
{"Extracting models and firmware", 30, true, inst.stepExtractData},
|
||||
{"Extracting scripts", 48, true, inst.stepExtractScripts},
|
||||
{"Configuring system", 55, false, inst.stepConfigureSystem},
|
||||
{"Setting up USB driver", 62, false, inst.stepSetupLibusb},
|
||||
{"Setting up USB library", 62, false, inst.stepSetupLibusb},
|
||||
{"Setting up Python environment", 70, false, inst.stepSetupPython},
|
||||
{"Installing USB device driver", 76, false, inst.stepInstallUSBDriver},
|
||||
{"Installing media tools", 78, false, inst.stepInstallFfmpeg},
|
||||
{"Writing configuration", 85, true, inst.stepWriteConfig},
|
||||
{"Verifying installation", 90, false, inst.stepVerify},
|
||||
@ -325,6 +326,10 @@ func (inst *Installer) stepSetupPython(config InstallConfig) error {
|
||||
return inst.setupPythonVenv(config.InstallDir)
|
||||
}
|
||||
|
||||
func (inst *Installer) stepInstallUSBDriver(config InstallConfig) error {
|
||||
return installUSBDriver(config.InstallDir)
|
||||
}
|
||||
|
||||
func (inst *Installer) stepVerify(config InstallConfig) error {
|
||||
binName := "edge-ai-server"
|
||||
if runtime.GOOS == "windows" {
|
||||
|
||||
@ -102,6 +102,11 @@ func checkLibusbInstalled() bool {
|
||||
return exec.Command("brew", "list", "libusb").Run() == nil
|
||||
}
|
||||
|
||||
// installUSBDriver is a no-op on macOS (libusb handles USB access).
|
||||
func installUSBDriver(installDir string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func removeQuarantine(installDir string) {
|
||||
binPath := filepath.Join(installDir, "edge-ai-server")
|
||||
exec.Command("xattr", "-dr", "com.apple.quarantine", binPath).Run()
|
||||
|
||||
@ -92,6 +92,11 @@ func checkLibusbInstalled() bool {
|
||||
return exec.Command("dpkg", "-s", "libusb-1.0-0-dev").Run() == nil
|
||||
}
|
||||
|
||||
// installUSBDriver is a no-op on Linux (udev rules handle USB access).
|
||||
func installUSBDriver(installDir string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func removeQuarantine(installDir string) {
|
||||
// No-op on Linux
|
||||
}
|
||||
|
||||
@ -129,9 +129,86 @@ func installLibusb(installDir string) error {
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Extract and install WinUSB driver for Kneron devices
|
||||
if err := installWinUSBDriver(installDir); err != nil {
|
||||
return err
|
||||
// 2. Extract WinUSB driver files (for manual fallback)
|
||||
extractWinUSBDriverFiles(installDir)
|
||||
|
||||
// 3. Install WinUSB driver via KneronPLUS SDK (uses libwdi internally)
|
||||
// This is called after Python venv + kp wheel are installed (step 7),
|
||||
// so we defer the actual driver install to postInstallDriver().
|
||||
// Here we just extract the files.
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// extractWinUSBDriverFiles extracts INF and co-installer DLLs from payload
|
||||
// for manual fallback (Zadig). The actual driver install happens via kp SDK.
|
||||
func extractWinUSBDriverFiles(installDir string) {
|
||||
driverDir := filepath.Join(installDir, "drivers")
|
||||
os.MkdirAll(filepath.Join(driverDir, "amd64"), 0755)
|
||||
|
||||
driverFiles := map[string]string{
|
||||
"payload/drivers/kneron_winusb.inf": filepath.Join(driverDir, "kneron_winusb.inf"),
|
||||
"payload/drivers/amd64/WdfCoInstaller01011.dll": filepath.Join(driverDir, "amd64", "WdfCoInstaller01011.dll"),
|
||||
"payload/drivers/amd64/winusbcoinstaller2.dll": filepath.Join(driverDir, "amd64", "winusbcoinstaller2.dll"),
|
||||
}
|
||||
|
||||
for src, dst := range driverFiles {
|
||||
data, err := payloadFS.ReadFile(src)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
os.WriteFile(dst, data, 0644)
|
||||
}
|
||||
}
|
||||
|
||||
// installUSBDriver installs WinUSB driver via KneronPLUS SDK (libwdi).
|
||||
func installUSBDriver(installDir string) error {
|
||||
return installKneronDriverViaSDK(installDir)
|
||||
}
|
||||
|
||||
// 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.
|
||||
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
|
||||
try:
|
||||
import kp
|
||||
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}")
|
||||
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")))
|
||||
|
||||
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)))
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user