mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
Make process wait optional
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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).");
|
||||
}
|
||||
|
||||
@@ -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 = 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]
|
||||
|
||||
Reference in New Issue
Block a user