diff --git a/src/Rust/src/commands/apply.rs b/src/Rust/src/commands/apply.rs index 18e122d4..81a6b51a 100644 --- a/src/Rust/src/commands/apply.rs +++ b/src/Rust/src/commands/apply.rs @@ -14,6 +14,7 @@ pub fn apply<'a>( package: Option<&PathBuf>, exe_args: Option>, noelevate: bool, + runhooks: bool, ) -> Result<()> { if wait_for_parent { if let Err(e) = shared::wait_for_parent_to_exit(60_000) { @@ -21,7 +22,7 @@ pub fn apply<'a>( } } - if let Err(e) = apply_package_impl(&root_path, &app, package, exe_args.clone(), noelevate) { + if let Err(e) = apply_package_impl(&root_path, &app, package, exe_args.clone(), noelevate, runhooks) { error!("Error applying package: {}", e); if !restart { return Err(e); @@ -37,13 +38,17 @@ pub fn apply<'a>( } #[cfg(not(target_os = "linux"))] -fn apply_package_impl<'a>(root_path: &PathBuf, app: &Manifest, package: Option<&PathBuf>, exe_args: Option>, noelevate: bool) -> Result<()> { +fn apply_package_impl<'a>( + root_path: &PathBuf, + app: &Manifest, + package: Option<&PathBuf>, + exe_args: Option>, + noelevate: bool, + runhooks: bool, +) -> Result<()> { let mut package_manifest: Option = None; let mut package_bundle: Option> = None; - #[cfg(target_os = "windows")] - let _mutex = crate::windows::create_global_mutex(&app)?; - if let Some(pkg) = package { info!("Loading package from argument '{}'.", pkg.to_string_lossy()); let bun = bundle::load_bundle_from_file(&pkg)?; @@ -85,15 +90,20 @@ fn apply_package_impl<'a>(root_path: &PathBuf, app: &Manifest, package: Option<& } } - #[cfg(target_os = "windows")] - if !crate::windows::prerequisite::prompt_and_install_all_missing(&package_manifest, Some(&app.version))? { - bail!("Stopping apply. Pre-requisites are missing."); - } - info!("Applying package to current: {}", found_version); #[cfg(target_os = "windows")] - crate::windows::run_hook(&app, &root_path, "--veloapp-obsolete", 15); + { + if !crate::windows::prerequisite::prompt_and_install_all_missing(&package_manifest, Some(&app.version))? { + bail!("Stopping apply. Pre-requisites are missing and user cancelled."); + } + + if runhooks { + crate::windows::run_hook(&app, &root_path, "--veloapp-obsolete", 15); + } else { + info!("Skipping --veloapp-obsolete hook."); + } + } let current_dir = app.get_current_path(&root_path); if let Err(e) = shared::replace_dir_with_rollback(current_dir.clone(), || { @@ -110,19 +120,31 @@ fn apply_package_impl<'a>(root_path: &PathBuf, app: &Manifest, package: Option<& } #[cfg(target_os = "windows")] - if let Err(e) = package_manifest.write_uninstall_entry(root_path) { - warn!("Failed to write uninstall entry ({}).", e); - } + { + if let Err(e) = package_manifest.write_uninstall_entry(root_path) { + warn!("Failed to write uninstall entry ({}).", e); + } - #[cfg(target_os = "windows")] - crate::windows::run_hook(&package_manifest, &root_path, "--veloapp-updated", 15); + if runhooks { + crate::windows::run_hook(&package_manifest, &root_path, "--veloapp-updated", 15); + } else { + info!("Skipping --veloapp-updated hook."); + } + } info!("Package applied successfully."); Ok(()) } #[cfg(target_os = "linux")] -fn apply_package_impl<'a>(root_path: &PathBuf, app: &Manifest, package: Option<&PathBuf>, exe_args: Option>, noelevate: bool) -> Result<()> { +fn apply_package_impl<'a>( + root_path: &PathBuf, + app: &Manifest, + package: Option<&PathBuf>, + exe_args: Option>, + noelevate: bool, + _runhooks: bool, +) -> Result<()> { // on linux, the current "dir" is actually an AppImage file which we need to replace. let pkg = package.ok_or(anyhow!("Package is required"))?; diff --git a/src/Rust/src/commands/install.rs b/src/Rust/src/commands/install.rs index 87bf2dcf..9d9f434e 100644 --- a/src/Rust/src/commands/install.rs +++ b/src/Rust/src/commands/install.rs @@ -36,7 +36,7 @@ pub fn install(debug_pkg: Option<&PathBuf>, install_to: Option<&PathBuf>) -> Res info!(" Package Machine Architecture: {}", &app.machine_architecture); info!(" Package Runtime Dependencies: {}", &app.runtime_dependencies); - let _mutex = windows::create_global_mutex(&app)?; + let _mutex = shared::retry_io(|| windows::create_global_mutex(&app))?; if !windows::prerequisite::prompt_and_install_all_missing(&app, None)? { info!("Cancelling setup. Pre-requisites not installed."); diff --git a/src/Rust/src/commands/start.rs b/src/Rust/src/commands/start.rs index 2f8f12bc..8186bad6 100644 --- a/src/Rust/src/commands/start.rs +++ b/src/Rust/src/commands/start.rs @@ -97,7 +97,7 @@ fn try_legacy_migration(root_dir: &PathBuf, app: &bundle::Manifest) -> Result<() info!("Applying latest full package..."); let buf = Path::new(&package.file_path).to_path_buf(); - super::apply(&root_dir, &app, false, false, Some(&buf), None, true)?; + super::apply(&root_dir, &app, false, false, Some(&buf), None, true, false)?; info!("Removing old app-* folders..."); shared::delete_app_prefixed_folders(&root_dir)?; diff --git a/src/Rust/src/update.rs b/src/Rust/src/update.rs index f49f3444..73457277 100644 --- a/src/Rust/src/update.rs +++ b/src/Rust/src/update.rs @@ -143,14 +143,16 @@ fn apply(matches: &ArgMatches) -> Result<()> { None => bail!("Package (--package) argument is required on linux."), Some(p) => { let (root_path, app) = shared::detect_current_manifest(p)?; - commands::apply(&root_path, &app, restart, wait_for_parent, package, exe_args, noelevate) + commands::apply(&root_path, &app, restart, wait_for_parent, package, exe_args, noelevate, true) } } } #[cfg(not(target_os = "linux"))] { let (root_path, app) = shared::detect_current_manifest()?; - commands::apply(&root_path, &app, restart, wait_for_parent, package, exe_args, noelevate) + #[cfg(target_os = "windows")] + let _mutex = shared::retry_io(|| windows::create_global_mutex(&app))?; + commands::apply(&root_path, &app, restart, wait_for_parent, package, exe_args, noelevate, true) } } @@ -170,6 +172,8 @@ fn start(matches: &ArgMatches) -> Result<()> { warn!("Legacy args format is deprecated and will be removed in a future release. Please update your application to use the new format."); } + let (_root_path, app) = shared::detect_current_manifest()?; + let _mutex = shared::retry_io(|| windows::create_global_mutex(&app))?; commands::start(wait_for_parent, exe_name, exe_args, legacy_args) } diff --git a/src/Rust/src/windows/util.rs b/src/Rust/src/windows/util.rs index 44a2d596..52f95940 100644 --- a/src/Rust/src/windows/util.rs +++ b/src/Rust/src/windows/util.rs @@ -28,8 +28,9 @@ pub fn run_hook(app: &shared::bundle::Manifest, root_path: &PathBuf, hook_name: let args = vec![hook_name, &ver_string]; if let Err(e) = run_process_no_console_and_wait(&main_exe_path, args, ¤t_path, Some(Duration::from_secs(timeout_secs))) { warn!("Error running hook {}: {} (took {}ms)", hook_name, e, sw.ms()); + } else { + info!("Hook executed successfully (took {}ms)", sw.ms()); } - info!("Hook executed successfully (took {}ms)", sw.ms()); // in case the hook left running processes let _ = shared::force_stop_package(&root_path); } diff --git a/src/Rust/tests/commands.rs b/src/Rust/tests/commands.rs index 2e1da66d..a51f8366 100644 --- a/src/Rust/tests/commands.rs +++ b/src/Rust/tests/commands.rs @@ -41,7 +41,7 @@ pub fn test_install_apply_uninstall() { let pkg_name_apply = "AvaloniaCrossPlat-1.0.15-win-full.nupkg"; let nupkg_apply = fixtures.join(pkg_name_apply); - commands::apply(&root_dir, &app, false, false, Some(&nupkg_apply), None, true).unwrap(); + commands::apply(&root_dir, &app, false, false, Some(&nupkg_apply), None, true, false).unwrap(); let (root_dir, app) = shared::detect_manifest_from_update_path(&tmp_buf.join("Update.exe")).unwrap(); assert!(semver::Version::parse("1.0.15").unwrap() == app.version); diff --git a/src/Velopack/VelopackApp.cs b/src/Velopack/VelopackApp.cs index 0cea79cc..9b7c09f6 100644 --- a/src/Velopack/VelopackApp.cs +++ b/src/Velopack/VelopackApp.cs @@ -163,13 +163,14 @@ namespace Velopack VelopackHook defaultBlock = ((v) => { }); var fastExitlookup = new[] { new { Key = "--veloapp-install", Value = _install ?? defaultBlock }, - new { Key = "--squirrel-install", Value = _install ?? defaultBlock }, new { Key = "--veloapp-updated", Value = _update ?? defaultBlock }, - new { Key = "--squirrel-updated", Value = _update ?? defaultBlock }, new { Key = "--veloapp-obsolete", Value = _obsolete ?? defaultBlock }, - new { Key = "--squirrel-obsolete", Value = _obsolete ?? defaultBlock }, new { Key = "--veloapp-uninstall", Value = _uninstall ?? defaultBlock }, - new { Key = "--squirrel-uninstall", Value = _uninstall ?? defaultBlock }, + // ignore the legacy hooks + new { Key = "--squirrel-install", Value = defaultBlock }, + new { Key = "--squirrel-updated", Value = defaultBlock }, + new { Key = "--squirrel-obsolete", Value = defaultBlock }, + new { Key = "--squirrel-uninstall", Value = defaultBlock }, }.ToDictionary(k => k.Key, v => v.Value, StringComparer.OrdinalIgnoreCase); if (args.Length >= 2 && fastExitlookup.ContainsKey(args[0])) { try {