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)?;
|
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...");
|
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);
|
info!("Elevated process has exited ({:?}).", result);
|
||||||
return Ok(new_locator);
|
return Ok(new_locator);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ pub enum OperationWait {
|
|||||||
|
|
||||||
pub fn operation_wait(wait: OperationWait) {
|
pub fn operation_wait(wait: OperationWait) {
|
||||||
if let OperationWait::WaitPid(pid) = wait {
|
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);
|
warn!("Failed to wait for process ({}) to exit ({}). Continuing...", pid, e);
|
||||||
}
|
}
|
||||||
} else if let OperationWait::WaitParent = wait {
|
} 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);
|
warn!("Failed to wait for parent process to exit ({}). Continuing...", e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ pub fn run_hook(locator: &VelopackLocator, hook_name: &str, timeout_secs: u64) -
|
|||||||
|
|
||||||
let cmd = cmd.unwrap();
|
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) => {
|
Ok(WaitResult::NoWaitRequired) => {
|
||||||
warn!("Was unable to wait for hook (it may have exited too quickly).");
|
warn!("Was unable to wait for hook (it may have exited too quickly).");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use windows::{
|
|||||||
Security::{GetTokenInformation, TokenElevation, TOKEN_ELEVATION},
|
Security::{GetTokenInformation, TokenElevation, TOKEN_ELEVATION},
|
||||||
System::Threading::{
|
System::Threading::{
|
||||||
CreateProcessW, GetCurrentProcess, GetExitCodeProcess, GetProcessId, GetProcessTimes, OpenProcess, OpenProcessToken,
|
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,
|
PROCESS_BASIC_INFORMATION, PROCESS_QUERY_LIMITED_INFORMATION, PROCESS_SYNCHRONIZE, PROCESS_TERMINATE, STARTUPINFOW,
|
||||||
STARTUPINFOW_FLAGS,
|
STARTUPINFOW_FLAGS,
|
||||||
},
|
},
|
||||||
@@ -394,14 +394,30 @@ pub enum WaitResult {
|
|||||||
NoWaitRequired,
|
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();
|
let process = *process.as_ref();
|
||||||
if process.is_invalid() {
|
if process.is_invalid() {
|
||||||
return Ok(WaitResult::NoWaitRequired);
|
return Ok(WaitResult::NoWaitRequired);
|
||||||
}
|
}
|
||||||
|
|
||||||
let ms = duration_to_ms(dur);
|
let ms = if let Some(dur) = dur {
|
||||||
info!("Waiting {}ms for process handle to exit.", ms);
|
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 {
|
unsafe {
|
||||||
match WaitForSingleObject(process, ms) {
|
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);
|
info!("Waiting for process pid-{} to exit.", pid);
|
||||||
let handle = open_process(PROCESS_SYNCHRONIZE, false, 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.");
|
info!("Reading parent process information.");
|
||||||
let basic_info = ProcessBasicInformation;
|
let basic_info = ProcessBasicInformation;
|
||||||
let my_handle = unsafe { GetCurrentProcess() };
|
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);
|
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]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user