fn kill_process_if()

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(())
	}
}