diff --git a/Changelog.md b/Changelog.md index d5c273e6f..f2033f2d2 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,6 +8,7 @@ - 修复多个代理集合包含同名节点时,代理组中的节点变灰并显示 ambiguous、无法选择的问题 - 修复手动更新时重复下载后台已下载的安装包、启动时选「稍后」后每次启动都重新下载的问题 - 修复下载更新时镜像缓慢或卡住不会切换下载地址、点击「取消」无法中止下载的问题 +- 修复关闭「自动检查更新」后,启动时仍弹出已下载更新的安装提示的问题 - 修复从 Dock 退出、注销或关机时,应用可能长时间卡住无法退出的问题 **🖥️ Windows** diff --git a/src-tauri/src/core/updater.rs b/src-tauri/src/core/updater.rs index 77f06fe87..0a0324a88 100644 --- a/src-tauri/src/core/updater.rs +++ b/src-tauri/src/core/updater.rs @@ -15,6 +15,7 @@ use tokio_util::sync::CancellationToken; pub struct SilentUpdater { update_ready: AtomicBool, manual_cancel: Mutex>, + background_cancel: Mutex>, } singleton!(SilentUpdater, SILENT_UPDATER); @@ -24,6 +25,7 @@ impl SilentUpdater { Self { update_ready: AtomicBool::new(false), manual_cancel: Mutex::new(None), + background_cancel: Mutex::new(None), } } @@ -328,6 +330,11 @@ impl SilentUpdater { /// Installs a newer cached update before normal startup, if the user confirms. pub async fn try_install_on_startup(&self, app_handle: &tauri::AppHandle) -> bool { + if !Config::verge().await.latest_arc().auto_check_update.unwrap_or(true) { + Self::delete_cache(); + return false; + } + let current_version = env!("CARGO_PKG_VERSION"); let meta = match Self::read_cache_meta() { @@ -466,6 +473,16 @@ impl SilentUpdater { cancel.cancel(); } } + + /// Drops the downloaded update and aborts a background download in flight. + pub fn discard_pending(&self) { + let cancel = self.background_cancel.lock().take(); + if let Some(cancel) = cancel { + cancel.cancel(); + } + self.update_ready.store(false, Ordering::Release); + Self::delete_cache(); + } } impl SilentUpdater { @@ -575,6 +592,9 @@ impl SilentUpdater { impl SilentUpdater { async fn check_and_download(&self, app_handle: &tauri::AppHandle) -> Result<()> { + // Registered before reading the switch, so `discard_pending` either cancels it or ran first. + let cancel = CancellationToken::new(); + *self.background_cancel.lock() = Some(cancel.clone()); let auto_check = Config::verge().await.latest_arc().auto_check_update.unwrap_or(true); if !auto_check { logging!(debug, Type::System, "Silent update skipped: auto_check_update is false"); @@ -623,11 +643,31 @@ impl SilentUpdater { logging!(info, Type::System, "Silent updater: v{version} already cached"); } else { logging!(info, Type::System, "Silent updater: downloading v{version}..."); - let bytes = download(&update, |_| {}).await?; + let downloaded = tokio::select! { + bytes = download(&update, |_| {}) => Some(bytes), + () = cancel.cancelled() => None, + }; + let Some(bytes) = downloaded else { + logging!(info, Type::System, "Silent updater: download cancelled"); + return Ok(()); + }; + let bytes = bytes?; logging!(info, Type::System, "Silent updater: download complete"); Self::write_cache(&bytes, &version)?; } + // Serialized with `discard_pending` in the verge patch, which holds the same lock. + let _config_write = Config::lock_config_write().await; + if cancel.is_cancelled() || !Config::verge().await.latest_arc().auto_check_update.unwrap_or(true) { + logging!( + info, + Type::System, + "Silent updater: auto check was disabled, discarding v{version}" + ); + Self::delete_cache(); + return Ok(()); + } + self.update_ready.store(true, Ordering::Release); logging!( diff --git a/src-tauri/src/feat/config.rs b/src-tauri/src/feat/config.rs index 7bcb17a80..797911037 100644 --- a/src-tauri/src/feat/config.rs +++ b/src-tauri/src/feat/config.rs @@ -1,6 +1,6 @@ use crate::{ config::{Config, IVerge}, - core::{CoreManager, autostart, handle, hotkey, logger, proxy_control, tray}, + core::{CoreManager, SilentUpdater, autostart, handle, hotkey, logger, proxy_control, tray}, module::{auto_backup::AutoBackupManager, lightweight}, }; use anyhow::Result; @@ -310,6 +310,9 @@ pub(super) async fn apply_verge_patch_locked( // A failed patch rolls back to what the user already had; it never invents a value for them. process_terminated_flags(update_flags, patch).await?; transaction.commit(); + if patch.auto_check_update == Some(false) { + SilentUpdater::global().discard_pending(); + } announce_verge_change(); logging_error!(Type::Backup, AutoBackupManager::global().refresh_settings().await);