in src/process.rs [82:166]
fn kill_process_if(
log: &slog::Logger,
process: &RunningProcess,
path: &Path,
) -> Result<(), Box<dyn error::Error>> {
use winapi::shared::minwindef::MAX_PATH;
use winapi::um::handleapi::CloseHandle;
use winapi::um::processthreadsapi::{OpenProcess, TerminateProcess};
use winapi::um::psapi::GetModuleFileNameExW;
use winapi::um::winnt::{PROCESS_QUERY_INFORMATION, PROCESS_TERMINATE, PROCESS_VM_READ};
info!(
log,
"Kill process if found: {}, {}", process.id, process.name
);
unsafe {
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684320(v=vs.85).aspx
let handle = OpenProcess(
PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE,
0,
process.id,
);
if handle.is_null() {
return Err(
io::Error::new(
io::ErrorKind::Other,
format!(
"Failed to open process: {}",
util::get_last_error_message()?
),
)
.into(),
);
}
let mut raw_path = [0u16; MAX_PATH];
let len = GetModuleFileNameExW(
handle,
ptr::null_mut(),
raw_path.as_mut_ptr(),
MAX_PATH as DWORD,
) as usize;
if len == 0 {
CloseHandle(handle);
return Err(
io::Error::new(
io::ErrorKind::Other,
format!(
"Failed to get process file name: {}",
util::get_last_error_message()?
),
)
.into(),
);
}
let process_path = PathBuf::from(from_utf16(&raw_path[0..len])?);
if process_path != path {
CloseHandle(handle);
return Ok(());
}
info!(
log,
"Found {} running, pid {}, attempting to kill...", process.name, process.id
);
if TerminateProcess(handle, 0) != TRUE {
return Err(io::Error::new(io::ErrorKind::Other, "Failed to kill process").into());
}
info!(
log,
"Successfully killed {}, pid {}", process.name, process.id
);
CloseHandle(handle);
Ok(())
}
}