hw 0.2.3

强大而统一的跨平台硬件监控工具
use std::{path::Path, time::Duration};

use e_utils::{cmd::Cmd, AnyResult};
use sysinfo::{Pid, ProcessesToUpdate, System};

pub fn kill_name(name: impl AsRef<std::ffi::OsStr>) -> AnyResult<()> {
  let name = name.as_ref().to_ascii_lowercase();
  let mut sys = System::new();
  sys.refresh_processes(ProcessesToUpdate::All, true);
  for (_pid, process) in sys.processes() {
    if process.name().to_ascii_lowercase() == name {
      process.kill();
    }
  }
  Ok(())
}
pub fn query_name(name: impl AsRef<std::ffi::OsStr>) -> AnyResult<Vec<Pid>> {
  let name = name.as_ref().to_ascii_lowercase();
  let mut sys = System::new();
  sys.refresh_processes(ProcessesToUpdate::All, true);
  let mut pids: Vec<Pid> = vec![];
  for (pid, process) in sys.processes() {
    if process.name().to_ascii_lowercase() == name {
      pids.push(*pid);
    }
  }
  Ok(pids)
}
pub fn kill(pids: Vec<Pid>) -> AnyResult<()> {
  let mut sys = System::new();
  sys.refresh_processes(ProcessesToUpdate::All, true);
  for pid in pids {
    if let Some(process) = sys.process(pid) {
      process.kill();
    }
  }
  Ok(())
}

/// Run
pub fn run(name: &str, cwd: impl AsRef<Path>) -> AnyResult<Vec<Pid>> {
  let pids: Vec<Pid> = query_name(name)?;
  if !pids.is_empty() {
    crate::dp(format!("{} is already running with PIDs: {:?}", name, pids,));
    return Ok(pids);
  } else {
    let _pid = Cmd::new(name).flags(0).cwd(cwd).a_spawn()?.id().map(Pid::from_u32);
    for i in 0..10 {
      let pids: Vec<Pid> = query_name(name)?;
      if !pids.is_empty() {
        return Ok(pids);
      }
      crate::wp(format!("{name} 检查进程 第 {i}"));
      std::thread::sleep(Duration::from_secs(1));
    }
    Err(format!("{name} 无法运行或控制进程").into())
  }
}