#[cfg(unix)]
pub fn verify_process_running(pid: u32) -> bool {
use std::process::Command;
let output = Command::new("kill").args(["-0", &pid.to_string()]).output();
if let Ok(output) = output {
output.status.success()
} else {
false
}
}
#[cfg(windows)]
pub fn verify_process_running(pid: u32) -> bool {
use std::process::Command;
let output = Command::new("tasklist")
.args(&["/FI", &format!("PID eq {}", pid), "/NH"])
.output();
if let Ok(output) = output {
let output_str = String::from_utf8_lossy(&output.stdout);
output_str.contains(&pid.to_string())
} else {
false
}
}
#[cfg(target_os = "windows")]
pub fn detect_windows_terminal() -> String {
use std::env;
if let Ok(output) = std::process::Command::new("wmic.exe")
.args(&[
"process",
"where",
&format!("processid={}", std::process::id()),
"get",
"parentprocessid",
])
.output()
{
let output_str = String::from_utf8_lossy(&output.stdout);
if let Some(ppid_str) = output_str.lines().nth(1) {
let ppid = ppid_str.trim();
if !ppid.is_empty() {
if let Ok(parent_output) = std::process::Command::new("wmic.exe")
.args(&[
"process",
"where",
&format!("processid={}", ppid),
"get",
"name",
])
.output()
{
let parent_name = String::from_utf8_lossy(&parent_output.stdout);
if let Some(name) = parent_name.lines().nth(1) {
let name = name.trim();
if name.eq_ignore_ascii_case("cmd.exe") {
return "Command Prompt (cmd.exe)".to_string();
} else if name.eq_ignore_ascii_case("powershell.exe")
|| name.eq_ignore_ascii_case("pwsh.exe")
{
return "PowerShell".to_string();
} else if name.eq_ignore_ascii_case("windowsterminal.exe") {
return "Windows Terminal".to_string();
} else if name.eq_ignore_ascii_case("conhost.exe") {
return "Console Host".to_string();
} else if !name.is_empty() {
return name.to_string();
}
}
}
}
}
}
"your terminal application".to_string()
}
#[cfg(target_os = "linux")]
pub fn detect_linux_terminal() -> String {
use std::env;
if let Ok(term) = env::var("TERM_PROGRAM") {
return term;
}
let output = std::process::Command::new("ps")
.args(["-p", &format!("{}", std::process::id()), "-o", "args="])
.output();
if let Ok(output) = output {
let process_name = String::from_utf8_lossy(&output.stdout);
if process_name.contains("gnome-terminal") {
return "gnome-terminal".to_string();
} else if process_name.contains("konsole") {
return "konsole".to_string();
} else if process_name.contains("xterm") {
return "xterm".to_string();
} else if process_name.contains("alacritty") {
return "alacritty".to_string();
} else if process_name.contains("kitty") {
return "kitty".to_string();
} else if process_name.contains("terminator") {
return "terminator".to_string();
}
}
"your terminal emulator".to_string()
}
#[cfg(target_os = "linux")]
pub fn detect_desktop_environment() -> String {
use std::env;
for var in &["XDG_CURRENT_DESKTOP", "DESKTOP_SESSION", "GDMSESSION"] {
if let Ok(val) = env::var(var) {
if !val.is_empty() {
if val.to_uppercase().contains("GNOME") {
return "GNOME".to_string();
} else if val.to_uppercase().contains("KDE") {
return "KDE".to_string();
} else if val.to_uppercase().contains("XFCE") {
return "XFCE".to_string();
} else if val.to_uppercase().contains("CINNAMON") {
return "Cinnamon".to_string();
} else if val.to_uppercase().contains("MATE") {
return "MATE".to_string();
} else {
return val;
}
}
}
}
"Unknown".to_string()
}
#[cfg(target_os = "macos")]
pub fn get_frontmost_terminal_app() -> String {
use std::process::Command;
let output = Command::new("osascript")
.arg("-e")
.arg("tell application \"System Events\" to get name of first process whose frontmost is true")
.output();
if let Ok(output) = output {
let app_name = String::from_utf8_lossy(&output.stdout).trim().to_string();
match app_name.as_str() {
"iTerm" | "iTerm2" => return "iTerm2".to_string(),
"Terminal" => return "Terminal".to_string(),
"Alacritty" => return "Alacritty".to_string(),
"kitty" => return "kitty".to_string(),
"Hyper" => return "Hyper".to_string(),
"WezTerm" => return "WezTerm".to_string(),
_ => {
if app_name.contains("Terminal") || app_name.contains("Console") {
return format!("{}.app", app_name);
}
}
}
}
String::new() }
#[cfg(target_os = "macos")]
pub fn detect_terminal_app() -> String {
use std::process::Command;
let frontmost_app = get_frontmost_terminal_app();
if !frontmost_app.is_empty() {
return frontmost_app;
}
let ppid = match Command::new("ps")
.args(["-o", "ppid=", "-p", &format!("{}", std::process::id())])
.output()
{
Ok(output) => {
let ppid_str = String::from_utf8_lossy(&output.stdout).trim().to_string();
ppid_str.parse::<u32>().unwrap_or(0)
}
Err(_) => 0,
};
let terminal_app = find_terminal_in_process_tree(ppid);
if !terminal_app.is_empty() {
return terminal_app;
}
"your terminal application (Terminal.app, iTerm2, etc.)".to_string()
}
#[cfg(target_os = "macos")]
pub fn find_terminal_in_process_tree(pid: u32) -> String {
use std::process::Command;
if pid == 0 {
return String::new();
}
let output = Command::new("ps")
.args(["-p", &pid.to_string(), "-o", "comm="])
.output();
if let Ok(output) = output {
let comm = String::from_utf8_lossy(&output.stdout).trim().to_string();
match comm.as_str() {
"iTerm2" | "iterm2" => return "iTerm2".to_string(),
"iTerm" => return "iTerm".to_string(),
"Terminal" => return "Terminal".to_string(),
"Alacritty" => return "Alacritty".to_string(),
"kitty" => return "kitty".to_string(),
"Hyper" => return "Hyper".to_string(),
"WezTerm" => return "WezTerm".to_string(),
_ => {}
}
if comm.contains("sh")
|| comm == "bash"
|| comm == "zsh"
|| comm == "fish"
|| comm.starts_with('-')
{
let ppid_output = Command::new("ps")
.args(["-p", &pid.to_string(), "-o", "ppid="])
.output();
if let Ok(ppid_output) = ppid_output {
let ppid_str = String::from_utf8_lossy(&ppid_output.stdout)
.trim()
.to_string();
if let Ok(ppid) = ppid_str.parse::<u32>() {
if ppid != 0 && ppid != pid {
return find_terminal_in_process_tree(ppid);
}
}
}
}
if comm.to_lowercase().contains("term") && !comm.contains("daemon") {
return format!("{}.app", comm);
}
}
let terminal_check = Command::new("ps").args(["-e", "-o", "comm="]).output();
if let Ok(output) = terminal_check {
let all_processes = String::from_utf8_lossy(&output.stdout);
for line in all_processes.lines() {
match line.trim() {
"iTerm2" => return "iTerm2".to_string(),
"iTerm" => return "iTerm".to_string(),
"Terminal" => return "Terminal".to_string(),
_ => {}
}
}
}
String::new()
}
#[cfg(target_os = "linux")]
pub fn is_running_as_sudo() -> bool {
std::env::var("SUDO_USER").is_ok()
}
#[cfg(target_os = "windows")]
pub fn is_defender_blocking_likely() -> bool {
let output = std::process::Command::new("powershell.exe")
.args(&[
"-Command",
"Get-MpPreference | Select-Object -ExpandProperty EnableExploitProtection",
])
.output();
if let Ok(output) = output {
let result = String::from_utf8_lossy(&output.stdout).trim();
return result == "True" || result == "1";
}
false
}