2025-08-06 17:59:57 +08:00
|
|
|
|
use std::fs;
|
2025-03-23 01:08:50 +08:00
|
|
|
|
use std::process::Command;
|
2025-03-21 18:00:16 +08:00
|
|
|
|
|
2025-03-27 11:30:03 +08:00
|
|
|
|
#[cfg(windows)]
|
|
|
|
|
|
use std::os::windows::process::CommandExt;
|
2025-03-21 18:00:16 +08:00
|
|
|
|
const CREATE_NO_WINDOW: u32 = 0x08000000;
|
|
|
|
|
|
// const DETACHED_PROCESS: u32 = 0x00000008;
|
2024-09-20 09:52:13 +08:00
|
|
|
|
|
|
|
|
|
|
pub fn kill(name: &str) -> String {
|
2025-03-27 11:30:03 +08:00
|
|
|
|
#[cfg(windows)]
|
2024-09-20 09:52:13 +08:00
|
|
|
|
Command::new("taskkill")
|
|
|
|
|
|
.args(&["/IM", name, "/F"])
|
2025-03-22 01:16:39 +08:00
|
|
|
|
.creation_flags(CREATE_NO_WINDOW)
|
2024-09-20 09:52:13 +08:00
|
|
|
|
.output()
|
|
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
|
|
|
|
format!("Killing {}", name)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn run_steam() -> std::io::Result<std::process::Output> {
|
2025-03-27 11:30:03 +08:00
|
|
|
|
#[cfg(target_os = "windows")]
|
2025-03-27 13:32:30 +08:00
|
|
|
|
return Command::new("cmd")
|
2024-09-20 09:52:13 +08:00
|
|
|
|
.args(&["/C", "start", "steam://run"])
|
2025-03-22 01:16:39 +08:00
|
|
|
|
.creation_flags(CREATE_NO_WINDOW)
|
2025-03-27 11:30:03 +08:00
|
|
|
|
.output();
|
|
|
|
|
|
|
2025-08-06 17:59:57 +08:00
|
|
|
|
#[cfg(target_os = "macos")]
|
|
|
|
|
|
Command::new("open").args(&["-a", "Steam"]).output()
|
2024-09-20 09:52:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn get_exe_path(name: &str) -> Result<String, std::io::Error> {
|
2025-03-23 01:08:50 +08:00
|
|
|
|
// [原理]
|
|
|
|
|
|
// Powershell 运行 Get-Process name | Select-Object path
|
|
|
|
|
|
// 有name.exe运行时返回
|
|
|
|
|
|
// Path
|
|
|
|
|
|
// ----
|
|
|
|
|
|
// 进程路径
|
|
|
|
|
|
let command = format!("Get-Process {} | Select-Object path", name);
|
2024-09-20 09:52:13 +08:00
|
|
|
|
let args = command.split_whitespace().collect::<Vec<&str>>();
|
2025-03-27 11:30:03 +08:00
|
|
|
|
#[cfg(windows)]
|
2025-03-23 01:08:50 +08:00
|
|
|
|
let output = Command::new("powershell.exe")
|
|
|
|
|
|
.args(&args)
|
|
|
|
|
|
.creation_flags(CREATE_NO_WINDOW)
|
|
|
|
|
|
.output()?;
|
2024-09-20 09:52:13 +08:00
|
|
|
|
|
2025-08-06 17:59:57 +08:00
|
|
|
|
#[cfg(target_os = "macos")]
|
|
|
|
|
|
let output = Command::new("osascript")
|
|
|
|
|
|
.args(&[
|
|
|
|
|
|
"-e",
|
|
|
|
|
|
&format!("tell application \"{}\" to get path to me", name),
|
|
|
|
|
|
])
|
|
|
|
|
|
.output()?;
|
2025-03-27 11:30:03 +08:00
|
|
|
|
|
2025-03-23 01:08:50 +08:00
|
|
|
|
let out = String::from_utf8_lossy(&output.stdout).to_string();
|
2024-09-20 09:52:13 +08:00
|
|
|
|
|
2025-03-23 01:08:50 +08:00
|
|
|
|
if out.contains("Path") {
|
|
|
|
|
|
let out = out.trim();
|
2024-09-20 09:52:13 +08:00
|
|
|
|
let spt: Vec<&str> = out.split("\r\n").collect();
|
2025-03-23 01:08:50 +08:00
|
|
|
|
|
|
|
|
|
|
if spt.len() > 2 {
|
|
|
|
|
|
return Ok(spt[2].to_string());
|
2024-09-20 09:52:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
Err(std::io::Error::new(
|
|
|
|
|
|
std::io::ErrorKind::Other,
|
|
|
|
|
|
"Failed to get executable path",
|
|
|
|
|
|
))
|
|
|
|
|
|
}
|
2025-03-21 16:02:47 +08:00
|
|
|
|
|
|
|
|
|
|
pub fn open_path(path: &str) -> Result<(), std::io::Error> {
|
2025-03-21 18:00:16 +08:00
|
|
|
|
// path中所有/ 转换为 \
|
|
|
|
|
|
let path = path.replace("/", "\\");
|
2025-11-04 23:33:36 +08:00
|
|
|
|
fs::create_dir_all(&path)?;
|
2025-08-06 17:59:57 +08:00
|
|
|
|
|
2025-03-27 11:30:03 +08:00
|
|
|
|
#[cfg(windows)]
|
2025-03-21 18:00:16 +08:00
|
|
|
|
Command::new("cmd.exe")
|
|
|
|
|
|
.args(["/c", "start", "", &path])
|
|
|
|
|
|
.creation_flags(CREATE_NO_WINDOW)
|
2025-03-21 16:02:47 +08:00
|
|
|
|
.spawn()
|
2025-03-21 18:00:16 +08:00
|
|
|
|
.unwrap();
|
2025-03-21 16:02:47 +08:00
|
|
|
|
Ok(())
|
|
|
|
|
|
}
|
2025-03-21 18:00:16 +08:00
|
|
|
|
|
2025-11-05 11:19:43 +08:00
|
|
|
|
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
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-03-21 18:00:16 +08:00
|
|
|
|
mod tests {
|
|
|
|
|
|
#[test]
|
|
|
|
|
|
fn test_open_path() {
|
|
|
|
|
|
let path = "D:\\Programs\\Steam";
|
|
|
|
|
|
println!("test open path: {}", path);
|
2025-11-04 23:33:36 +08:00
|
|
|
|
super::open_path(path).unwrap();
|
2025-03-21 18:00:16 +08:00
|
|
|
|
|
|
|
|
|
|
let path = "D:\\Programs\\Steam\\steamapps\\common\\Counter-Strike Global Offensive\\game\\bin\\win64";
|
|
|
|
|
|
println!("test open path: {}", path);
|
2025-11-04 23:33:36 +08:00
|
|
|
|
super::open_path(path).unwrap();
|
2025-03-21 18:00:16 +08:00
|
|
|
|
|
|
|
|
|
|
let path = "%appdata%/Wmpvp/demo";
|
|
|
|
|
|
println!("test open path: {}", path);
|
2025-11-04 23:33:36 +08:00
|
|
|
|
super::open_path(path).unwrap()
|
2025-03-21 18:00:16 +08:00
|
|
|
|
}
|
2025-03-23 01:08:50 +08:00
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
|
fn test_get_exe_path() {
|
2025-11-04 23:33:36 +08:00
|
|
|
|
let path = super::get_exe_path("steam").expect("failed");
|
2025-03-23 01:08:50 +08:00
|
|
|
|
println!("test get steam path: {}", path);
|
|
|
|
|
|
|
2025-11-04 23:33:36 +08:00
|
|
|
|
super::get_exe_path("not_running").expect("failed");
|
2025-03-23 01:08:50 +08:00
|
|
|
|
}
|
2025-03-21 18:00:16 +08:00
|
|
|
|
}
|