//! Tauri-Befehle, die die Oberfläche aufruft. use std::collections::HashMap; use std::sync::Arc; use std::time::Duration; use tauri::State; use crate::error::{AppError, AppResult}; use crate::managers::winget::WingetManager; use crate::managers::PackageManager; use crate::models::{ManagerId, ManagerInfo, Package, PackageDetails, Source}; use crate::process; /// Registrierte Paketmanager. pub struct Registry { managers: HashMap>, } impl Registry { /// Erstellt die Registry mit allen verfügbaren Implementierungen. pub fn new() -> Self { let mut managers: HashMap> = HashMap::new(); managers.insert(ManagerId::Winget, Arc::new(WingetManager::new())); Self { managers } } fn get(&self, id: ManagerId) -> AppResult> { self.managers .get(&id) .cloned() .ok_or_else(|| AppError::Command("Dieser Paketmanager wird noch nicht unterstützt.".to_owned())) } async fn detect_all(&self) -> Vec { let mut infos = Vec::new(); for manager in self.managers.values() { infos.push(manager.detect().await); } infos } } impl Default for Registry { fn default() -> Self { Self::new() } } fn logged(what: &str, result: AppResult) -> AppResult { if let Err(err) = &result { tracing::error!(%err, "{what} fehlgeschlagen"); } result } /// Erkennt alle Paketmanager (Pfad, Version, Zusatzkomponenten). #[tauri::command] pub async fn detect_managers(registry: State<'_, Registry>) -> AppResult> { Ok(registry.detect_all().await) } /// Sucht Pakete. #[tauri::command] pub async fn search_packages(registry: State<'_, Registry>, manager: ManagerId, query: String) -> AppResult> { let query = query.trim().to_owned(); if query.is_empty() { return Ok(Vec::new()); } logged("Paketsuche", registry.get(manager)?.search(&query).await) } /// Listet installierte Pakete. #[tauri::command] pub async fn list_installed(registry: State<'_, Registry>, manager: ManagerId) -> AppResult> { logged("Liste der installierten Pakete", registry.get(manager)?.list_installed().await) } /// Listet verfügbare Aktualisierungen. #[tauri::command] pub async fn list_updates(registry: State<'_, Registry>, manager: ManagerId) -> AppResult> { logged("Suche nach Aktualisierungen", registry.get(manager)?.list_updates().await) } /// Lädt Paketdetails. #[tauri::command] pub async fn get_package_details(registry: State<'_, Registry>, package: Package) -> AppResult { logged("Paketdetails", registry.get(package.manager)?.get_details(&package).await) } /// Listet die Quellen eines Managers. #[tauri::command] pub async fn list_sources(registry: State<'_, Registry>, manager: ManagerId) -> AppResult> { logged("Quellenliste", registry.get(manager)?.list_sources().await) } async fn run_powershell(script: &str, timeout: Duration) -> AppResult<()> { let shell = which::which("powershell") .map_err(|_| AppError::ManagerMissing("Windows PowerShell".to_owned()))?; let out = process::run(&shell, &["-NoLogo", "-NoProfile", "-NonInteractive", "-Command", script], timeout).await?; if out.code == Some(0) { Ok(()) } else { let detail = out.stderr.lines().find(|l| !l.trim().is_empty()).unwrap_or("unbekannter Fehler"); Err(AppError::Command(format!("Die Installation ist fehlgeschlagen: {detail}"))) } } /// Installiert das PowerShell-Modul `Microsoft.WinGet.Client` für den aktuellen Benutzer. #[tauri::command] pub async fn install_winget_module(registry: State<'_, Registry>) -> AppResult> { let script = "$ProgressPreference='SilentlyContinue'; $ErrorActionPreference='Stop'; \ Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Scope CurrentUser -Force | Out-Null; \ Install-Module -Name Microsoft.WinGet.Client -Scope CurrentUser -Repository PSGallery -Force"; logged("Modulinstallation", run_powershell(script, Duration::from_secs(300)).await)?; Ok(registry.detect_all().await) } /// Registriert bzw. installiert den „App-Installer“ (enthält WinGet). #[tauri::command] pub async fn install_app_installer(registry: State<'_, Registry>) -> AppResult> { let script = "$ProgressPreference='SilentlyContinue'; $ErrorActionPreference='Stop'; \ Add-AppxPackage -RegisterByFamilyName -MainPackage Microsoft.DesktopAppInstaller_8wekyb3d8bbwe"; logged("Installation des App-Installers", run_powershell(script, Duration::from_secs(300)).await)?; Ok(registry.detect_all().await) }