use anyhow::{Result, anyhow};
use std::thread;
use std::time::Duration;
use sysinfo::{ProcessRefreshKind, RefreshKind, System};
pub fn kill_process(pid: u32) -> Result<()> {
let mut sys = System::new_with_specifics(
RefreshKind::new().with_processes(ProcessRefreshKind::everything()),
);
sys.refresh_all();
let pid_obj = sysinfo::Pid::from_u32(pid);
if let Some(process) = sys.process(pid_obj) {
if process.kill() {
Ok(())
} else {
Err(anyhow!("无法终止进程 {pid} (可能需要管理员权限)"))
}
} else {
Err(anyhow!("进程 {pid} 不存在"))
}
}
pub fn kill_processes(pids: &[u32]) -> Vec<(u32, Result<()>)> {
pids.iter().map(|&pid| (pid, kill_process(pid))).collect()
}
pub fn kill_process_force(pid: u32) -> Result<()> {
{
let mut sys = System::new_with_specifics(
RefreshKind::new().with_processes(ProcessRefreshKind::everything()),
);
sys.refresh_all();
let pid_obj = sysinfo::Pid::from_u32(pid);
if sys.process(pid_obj).is_none() {
return Ok(());
}
}
for attempt in 1..=3 {
{
let mut sys = System::new_with_specifics(
RefreshKind::new().with_processes(ProcessRefreshKind::everything()),
);
sys.refresh_all();
let pid_obj = sysinfo::Pid::from_u32(pid);
if let Some(process) = sys.process(pid_obj) {
if process.kill() {
thread::sleep(Duration::from_millis(500));
sys.refresh_processes(sysinfo::ProcessesToUpdate::All);
if !sys.processes().contains_key(&pid_obj) {
return Ok(());
}
} else {
if attempt == 3 {
return Err(anyhow!("无法强制终止进程 {pid} (可能需要管理员权限)"));
}
}
} else {
return Ok(());
}
}
if attempt < 3 {
thread::sleep(Duration::from_millis(1000));
}
}
Err(anyhow!("强制终止进程 {pid} 失败,进程可能仍在运行"))
}
pub fn kill_processes_force(pids: &[u32]) -> Vec<(u32, Result<()>)> {
pids.iter()
.map(|&pid| (pid, kill_process_force(pid)))
.collect()
}