#[cfg(windows)]
extern crate winapi;
use core::mem;
use std::path::Path;
use std::fs;
#[cfg(windows)]
pub fn find_process_id(process_name: &str) -> Result<u32, String> {
use winapi::um::winnt;
use winapi::um::tlhelp32;
use winapi::um::winuser::WM_NULL;
use self::winapi::um::handleapi::CloseHandle;
use self::winapi::um::tlhelp32::{Process32Next, PROCESSENTRY32};
unsafe {
let mut process_info: tlhelp32::PROCESSENTRY32 = tlhelp32::PROCESSENTRY32::default();
process_info.dwSize = mem::size_of::<tlhelp32::PROCESSENTRY32>() as u32;
let processes_snapshot: winnt::HANDLE = tlhelp32::CreateToolhelp32Snapshot(tlhelp32::TH32CS_SNAPPROCESS, WM_NULL);
if processes_snapshot == winapi::um::handleapi::INVALID_HANDLE_VALUE {
return Err("Internal Error: Unable to process Windows handle.".to_string());
}
let process_info_ptr: *mut PROCESSENTRY32 = &mut process_info;
tlhelp32::Process32First(processes_snapshot, process_info_ptr);
let temp_exe_file = String::from_utf8(mem::transmute::<Vec<i8>, Vec<u8>>(remove_zeros(process_info.szExeFile.to_vec()))).unwrap();
let exe_file = temp_exe_file.split_whitespace().next().unwrap();
if process_name == exe_file {
CloseHandle(processes_snapshot);
return Ok(process_info.th32ProcessID);
}
while Process32Next(processes_snapshot, process_info_ptr) != 0 {
let temp_exe_file = String::from_utf8(mem::transmute::<Vec<i8>, Vec<u8>>(remove_zeros(process_info.szExeFile.to_vec()))).unwrap();
let exe_file = temp_exe_file.split(" ").next().unwrap();
if process_name == exe_file {
CloseHandle(processes_snapshot);
return Ok(process_info.th32ProcessID);
}
}
CloseHandle(processes_snapshot);
return Err(format!("Cannot find process with name {}.", process_name));
}
fn remove_zeros(vec: Vec<i8>) -> Vec<i8> {
let mut output: Vec<i8> = Vec::new();
for mt in vec {
if mt != 0 {
output.push(mt);
} else {
return output;
}
}
return output;
}
}
#[cfg(windows)]
pub fn is_process_running(process_id: &u32) -> bool {
use winapi::um::winnt;
use winapi::um;
use self::winapi::um::winnt::SYNCHRONIZE;
use self::winapi::shared::minwindef::FALSE;
use self::winapi::um::handleapi::CloseHandle;
use self::winapi::shared::winerror::WAIT_TIMEOUT;
unsafe {
let process: winnt::HANDLE = um::processthreadsapi::OpenProcess(SYNCHRONIZE, FALSE, *process_id);
let ret = um::synchapi::WaitForSingleObject(process, 0);
CloseHandle(process);
return ret == WAIT_TIMEOUT;
}
}
#[cfg(all(unix, not(target_os = "macos")))]
pub fn is_process_running(process_id: &u32) -> bool {
let mut result: bool = false;
let file = Path::new("/proc").join(process_id.to_string()).join("cmdline");
if file.exists() {
result = true;
}
result
}
#[cfg(all(unix, not(target_os = "macos")))]
pub fn find_process_id(process_name: &str) -> Result<u32, String> {
let paths = fs::read_dir("/proc/").unwrap();
let mut result: u32 = 0;
for path in paths {
let entry = path.unwrap();
let file = Path::new(entry.path().as_path()).join("cmdline");
if file.exists() {
let contents = fs::read_to_string(file).expect("Something went wrong reading the file");
if contents.contains(process_name) {
let string = entry.path().as_path().to_str().unwrap().replace("/proc/", "");
result = string.parse().unwrap()
}
}
}
if result == 0 {
return Err(format!("Cannot find process with name {}.", process_name));
}
Ok(result)
}
#[cfg(target_os = "macos")]
pub fn find_process_id(process_name: &str) -> Result<u32, String> {
use std::process::Command;
use std::str;
let pl = Command::new("pgrep")
.arg(process_name)
.output();
let output_vec: Vec<u8> = pl.unwrap().stdout;
let mut str_iter = str::from_utf8(&output_vec).unwrap().split_whitespace();;
let output = str_iter.next().unwrap().parse::<u32>();
if output.is_err(){
Err(String::from("Unable to find specified process id."))
}else {
Ok(output.unwrap())
}
}
#[cfg(target_os = "macos")]
pub fn is_process_running(process_id: &u32) -> bool {
use std::process::Command;
use std::str;
let pl = Command::new("kill")
.arg("-0")
.arg(format!("{}", process_id))
.output();
let output_vec: Vec<u8> = pl.unwrap().stdout;
output_vec.len() == 0
}