first
This commit is contained in:
91
src-tauri/src/winget.rs
Normal file
91
src-tauri/src/winget.rs
Normal file
@@ -0,0 +1,91 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::process::Command;
|
||||
use std::os::windows::process::CommandExt;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct Software {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub description: Option<String>,
|
||||
pub version: Option<String>,
|
||||
pub available_version: Option<String>,
|
||||
pub icon_url: Option<String>,
|
||||
pub status: String, // "idle", "pending", "installing", "success", "error"
|
||||
pub progress: f32,
|
||||
}
|
||||
|
||||
pub fn list_all_software() -> Vec<Software> {
|
||||
// winget list
|
||||
let output = Command::new("winget")
|
||||
.args(["list", "--accept-source-agreements"])
|
||||
.creation_flags(0x08000000) // CREATE_NO_WINDOW
|
||||
.output();
|
||||
|
||||
match output {
|
||||
Ok(out) => parse_winget_output(String::from_utf8_lossy(&out.stdout).to_string()),
|
||||
Err(_) => vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn list_updates() -> Vec<Software> {
|
||||
// winget upgrade
|
||||
let output = Command::new("winget")
|
||||
.args(["upgrade", "--accept-source-agreements"])
|
||||
.creation_flags(0x08000000)
|
||||
.output();
|
||||
|
||||
match output {
|
||||
Ok(out) => parse_winget_output(String::from_utf8_lossy(&out.stdout).to_string()),
|
||||
Err(_) => vec![],
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_winget_output(output: String) -> Vec<Software> {
|
||||
let mut softwares = Vec::new();
|
||||
let lines: Vec<&str> = output.lines().collect();
|
||||
|
||||
if lines.len() < 3 {
|
||||
return softwares;
|
||||
}
|
||||
|
||||
// 查找表头行以确定列偏移量
|
||||
// 通常格式: Name Id Version Available Source
|
||||
let header_idx = lines.iter().position(|l| l.contains("Id") && l.contains("Name")).unwrap_or(0);
|
||||
let header = lines[header_idx];
|
||||
|
||||
let id_pos = header.find("Id").unwrap_or(0);
|
||||
let version_pos = header.find("Version").unwrap_or(0);
|
||||
let available_pos = header.find("Available").unwrap_or(header.len());
|
||||
let source_pos = header.find("Source").unwrap_or(header.len());
|
||||
|
||||
for line in &lines[header_idx + 2..] {
|
||||
if line.trim().is_empty() || line.starts_with('-') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if line.len() < version_pos { continue; }
|
||||
|
||||
let name = line[..id_pos].trim().to_string();
|
||||
let id = line[id_pos..version_pos].trim().to_string();
|
||||
let version = line[version_pos..available_pos.min(line.len())].trim().to_string();
|
||||
|
||||
let available_version = if available_pos < line.len() {
|
||||
Some(line[available_pos..source_pos.min(line.len())].trim().to_string())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
softwares.push(Software {
|
||||
id,
|
||||
name,
|
||||
description: None,
|
||||
version: Some(version),
|
||||
available_version,
|
||||
icon_url: None,
|
||||
status: "idle".to_string(),
|
||||
progress: 0.0,
|
||||
});
|
||||
}
|
||||
|
||||
softwares
|
||||
}
|
||||
Reference in New Issue
Block a user