Make process wait optional

This commit is contained in:
Caelan Sayler
2025-05-23 21:04:35 +01:00
parent dfc87a391f
commit a0cca6afbc
4 changed files with 28 additions and 12 deletions

View File

@@ -58,7 +58,7 @@ pub fn apply_package_impl(old_locator: &VelopackLocator, package: &PathBuf, run_
let process_handle = process::run_process_as_admin(&exe_path, args, work_dir, false)?;
info!("Waiting (up to 10 minutes) for elevated process to exit...");
let result = process::wait_for_process_to_exit_with_timeout(process_handle, Duration::from_secs(10 * 60))?;
let result = process::wait_for_process_to_exit(process_handle, Some(Duration::from_secs(10 * 60)))?;
info!("Elevated process has exited ({:?}).", result);
return Ok(new_locator);
}

View File

@@ -13,11 +13,11 @@ pub enum OperationWait {
pub fn operation_wait(wait: OperationWait) {
if let OperationWait::WaitPid(pid) = wait {
if let Err(e) = process::wait_for_pid_to_exit(pid, Duration::from_secs(60)) {
if let Err(e) = process::wait_for_pid_to_exit(pid, Some(Duration::from_secs(60))) {
warn!("Failed to wait for process ({}) to exit ({}). Continuing...", pid, e);
}
} else if let OperationWait::WaitParent = wait {
if let Err(e) = process::wait_for_parent_to_exit(Duration::from_secs(60)) {
if let Err(e) = process::wait_for_parent_to_exit(Some(Duration::from_secs(60))) {
warn!("Failed to wait for parent process to exit ({}). Continuing...", e);
}
} else {

View File

@@ -40,7 +40,7 @@ pub fn run_hook(locator: &VelopackLocator, hook_name: &str, timeout_secs: u64) -
let cmd = cmd.unwrap();
match process::wait_for_process_to_exit_with_timeout(&cmd, Duration::from_secs(timeout_secs)) {
match process::wait_for_process_to_exit(&cmd, Some(Duration::from_secs(timeout_secs))) {
Ok(WaitResult::NoWaitRequired) => {
warn!("Was unable to wait for hook (it may have exited too quickly).");
}

View File

@@ -14,7 +14,7 @@ use windows::{
Security::{GetTokenInformation, TokenElevation, TOKEN_ELEVATION},
System::Threading::{
CreateProcessW, GetCurrentProcess, GetExitCodeProcess, GetProcessId, GetProcessTimes, OpenProcess, OpenProcessToken,
TerminateProcess, WaitForSingleObject, CREATE_NO_WINDOW, CREATE_UNICODE_ENVIRONMENT, PROCESS_ACCESS_RIGHTS,
TerminateProcess, WaitForSingleObject, CREATE_NO_WINDOW, CREATE_UNICODE_ENVIRONMENT, INFINITE, PROCESS_ACCESS_RIGHTS,
PROCESS_BASIC_INFORMATION, PROCESS_QUERY_LIMITED_INFORMATION, PROCESS_SYNCHRONIZE, PROCESS_TERMINATE, STARTUPINFOW,
STARTUPINFOW_FLAGS,
},
@@ -394,14 +394,30 @@ pub enum WaitResult {
NoWaitRequired,
}
pub fn wait_for_process_to_exit_with_timeout<T: AsRef<HANDLE>>(process: T, dur: Duration) -> IoResult<WaitResult> {
impl WaitResult {
pub fn code(&self) -> Option<u32> {
match self {
WaitResult::WaitTimeout => None,
WaitResult::ExitCode(c) => Some(*c),
WaitResult::NoWaitRequired => None,
}
}
}
pub fn wait_for_process_to_exit<T: AsRef<HANDLE>>(process: T, dur: Option<Duration>) -> IoResult<WaitResult> {
let process = *process.as_ref();
if process.is_invalid() {
return Ok(WaitResult::NoWaitRequired);
}
let ms = duration_to_ms(dur);
info!("Waiting {}ms for process handle to exit.", ms);
let ms = if let Some(dur) = dur {
let ms = duration_to_ms(dur);
info!("Waiting {}ms for process handle to exit.", ms);
ms
} else {
info!("Waiting indefinitely process handle to exit.");
INFINITE
};
unsafe {
match WaitForSingleObject(process, ms) {
@@ -416,13 +432,13 @@ pub fn wait_for_process_to_exit_with_timeout<T: AsRef<HANDLE>>(process: T, dur:
}
}
pub fn wait_for_pid_to_exit(pid: u32, dur: Duration) -> IoResult<WaitResult> {
pub fn wait_for_pid_to_exit(pid: u32, dur: Option<Duration>) -> IoResult<WaitResult> {
info!("Waiting for process pid-{} to exit.", pid);
let handle = open_process(PROCESS_SYNCHRONIZE, false, pid)?;
wait_for_process_to_exit_with_timeout(handle, dur)
wait_for_process_to_exit(handle, dur)
}
pub fn wait_for_parent_to_exit(dur: Duration) -> IoResult<WaitResult> {
pub fn wait_for_parent_to_exit(dur: Option<Duration>) -> IoResult<WaitResult> {
info!("Reading parent process information.");
let basic_info = ProcessBasicInformation;
let my_handle = unsafe { GetCurrentProcess() };
@@ -477,7 +493,7 @@ pub fn wait_for_parent_to_exit(dur: Duration) -> IoResult<WaitResult> {
}
info!("Waiting for parent process ({}) to exit.", info.InheritedFromUniqueProcessId);
wait_for_process_to_exit_with_timeout(parent_handle, dur)
wait_for_process_to_exit(parent_handle, dur)
}
#[test]