use std::fs; use std::process::Command; #[cfg(windows)] use std::os::windows::process::CommandExt; const CREATE_NO_WINDOW: u32 = 0x08000000; // const DETACHED_PROCESS: u32 = 0x00000008; pub fn kill(name: &str) -> String { #[cfg(windows)] Command::new("taskkill") .args(&["/IM", name, "/F"]) .creation_flags(CREATE_NO_WINDOW) .output() .unwrap(); format!("Killing {}", name) } pub fn run_steam() -> std::io::Result { #[cfg(target_os = "windows")] return Command::new("cmd") .args(&["/C", "start", "steam://run"]) .creation_flags(CREATE_NO_WINDOW) .output(); #[cfg(target_os = "macos")] Command::new("open").args(&["-a", "Steam"]).output() } pub fn get_exe_path(name: &str) -> Result { // [原理] // Powershell 运行 Get-Process name | Select-Object path // 有name.exe运行时返回 // Path // ---- // 进程路径 let command = format!("Get-Process {} | Select-Object path", name); #[cfg(windows)] let output = Command::new("powershell.exe") .args(&[ "-NoProfile", "-WindowStyle", "Hidden", "-Command", &command, ]) .creation_flags(CREATE_NO_WINDOW) .output()?; #[cfg(target_os = "macos")] let output = Command::new("osascript") .args(&[ "-e", &format!("tell application \"{}\" to get path to me", name), ]) .output()?; let out = String::from_utf8_lossy(&output.stdout).to_string(); if out.contains("Path") { let out = out.trim(); let spt: Vec<&str> = out.split("\r\n").collect(); if spt.len() > 2 { return Ok(spt[2].to_string()); } } Err(std::io::Error::new( std::io::ErrorKind::Other, "Failed to get executable path", )) } pub fn open_path(path: &str) -> Result<(), std::io::Error> { // path中所有/ 转换为 \ let path = path.replace("/", "\\"); fs::create_dir_all(&path)?; #[cfg(windows)] Command::new("cmd.exe") .args(["/c", "start", "", &path]) .creation_flags(CREATE_NO_WINDOW) .spawn() .unwrap(); Ok(()) } pub fn check_process_running(name: &str) -> bool { // 使用tasklist命令检查进程是否存在 #[cfg(windows)] { let output = Command::new("tasklist") .args(&["/FI", &format!("IMAGENAME eq {}", name)]) .creation_flags(CREATE_NO_WINDOW) .output(); if let Ok(output) = output { let stdout = String::from_utf8_lossy(&output.stdout); // 检查输出中是否包含进程名(排除表头) stdout.contains(name) && stdout.contains("exe") } else { false } } #[cfg(not(windows))] { // 对于非Windows系统,可以使用ps命令 let output = Command::new("pgrep") .arg("-f") .arg(name) .output(); if let Ok(output) = output { !output.stdout.is_empty() } else { false } } } mod tests { #[test] fn test_open_path() { let path = "D:\\Programs\\Steam"; println!("test open path: {}", path); super::open_path(path).unwrap(); let path = "D:\\Programs\\Steam\\steamapps\\common\\Counter-Strike Global Offensive\\game\\bin\\win64"; println!("test open path: {}", path); super::open_path(path).unwrap(); let path = "%appdata%/Wmpvp/demo"; println!("test open path: {}", path); super::open_path(path).unwrap() } #[test] fn test_get_exe_path() { let path = super::get_exe_path("steam").expect("failed"); println!("test get steam path: {}", path); super::get_exe_path("not_running").expect("failed"); } }