mirror of
https://github.com/kunkunsh/kunkun-ext-neohtop.git
synced 2025-04-11 17:29:45 +00:00
120 lines
3.6 KiB
Rust
120 lines
3.6 KiB
Rust
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
|
|
|
use sysinfo::{CpuExt, SystemExt, ProcessExt, System, PidExt, ProcessStatus};
|
|
use tauri::State;
|
|
use std::sync::Mutex;
|
|
|
|
struct AppState {
|
|
sys: Mutex<System>,
|
|
}
|
|
|
|
#[derive(serde::Serialize)]
|
|
struct ProcessInfo {
|
|
pid: u32,
|
|
ppid: u32,
|
|
name: String,
|
|
cpu_usage: f32,
|
|
memory_usage: u64,
|
|
status: String,
|
|
user: String,
|
|
command: String,
|
|
threads: Option<u32>,
|
|
}
|
|
|
|
#[derive(serde::Serialize)]
|
|
struct SystemStats {
|
|
cpu_usage: Vec<f32>,
|
|
memory_total: u64,
|
|
memory_used: u64,
|
|
uptime: u64,
|
|
load_avg: [f64; 3],
|
|
}
|
|
|
|
#[tauri::command]
|
|
async fn get_processes(state: State<'_, AppState>) -> Result<Vec<ProcessInfo>, String> {
|
|
let mut sys = state.sys.lock().map_err(|_| "Failed to lock system state")?;
|
|
sys.refresh_all();
|
|
|
|
Ok(sys.processes()
|
|
.iter()
|
|
.map(|(pid, process)| {
|
|
let threads = if cfg!(target_os = "macos") {
|
|
use std::process::Command;
|
|
Command::new("ps")
|
|
.args(["-o", "thcount=", "-p", &pid.as_u32().to_string()])
|
|
.output()
|
|
.ok()
|
|
.and_then(|output| {
|
|
String::from_utf8(output.stdout)
|
|
.ok()
|
|
.and_then(|s| s.trim().parse().ok())
|
|
})
|
|
} else {
|
|
None
|
|
};
|
|
|
|
let status = match process.status() {
|
|
ProcessStatus::Run => "R", // Running
|
|
ProcessStatus::Sleep => "S", // Sleeping
|
|
ProcessStatus::Idle => "I", // Idle
|
|
ProcessStatus::Zombie => "Z", // Zombie
|
|
ProcessStatus::Stop => "T", // Stopped
|
|
ProcessStatus::Dead => "X", // Dead
|
|
_ => "Unknown",
|
|
};
|
|
|
|
ProcessInfo {
|
|
pid: pid.as_u32(),
|
|
ppid: process.parent().unwrap_or(sysinfo::Pid::from(0)).as_u32(),
|
|
name: process.name().to_string(),
|
|
cpu_usage: process.cpu_usage(),
|
|
memory_usage: process.memory(),
|
|
status: status.to_string(),
|
|
user: process.user_id()
|
|
.map(|uid| uid.to_string())
|
|
.unwrap_or_else(|| "-".to_string()),
|
|
command: process.cmd().join(" "),
|
|
threads,
|
|
}
|
|
})
|
|
.collect())
|
|
}
|
|
|
|
#[tauri::command]
|
|
async fn get_system_stats(state: State<'_, AppState>) -> Result<SystemStats, String> {
|
|
let mut sys = state.sys.lock().map_err(|_| "Failed to lock system state")?;
|
|
sys.refresh_all();
|
|
|
|
let load_avg = sys.load_average();
|
|
Ok(SystemStats {
|
|
cpu_usage: sys.cpus().iter().map(|cpu| cpu.cpu_usage()).collect(),
|
|
memory_total: sys.total_memory(),
|
|
memory_used: sys.used_memory(),
|
|
uptime: sys.uptime(),
|
|
load_avg: [load_avg.one, load_avg.five, load_avg.fifteen],
|
|
})
|
|
}
|
|
|
|
#[tauri::command]
|
|
async fn kill_process(pid: u32, state: State<'_, AppState>) -> Result<bool, String> {
|
|
let sys = state.sys.lock().map_err(|_| "Failed to lock system state")?;
|
|
if let Some(process) = sys.process(sysinfo::Pid::from(pid as usize)) {
|
|
Ok(process.kill())
|
|
} else {
|
|
Ok(false)
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
tauri::Builder::default()
|
|
.manage(AppState {
|
|
sys: Mutex::new(System::new_all()),
|
|
})
|
|
.invoke_handler(tauri::generate_handler![
|
|
get_processes,
|
|
get_system_stats,
|
|
kill_process
|
|
])
|
|
.run(tauri::generate_context!())
|
|
.expect("error while running tauri application");
|
|
} |