fix(service): prompt reinstallation after path permission rejection

Address #7983 with a recovery dialog for Windows service error 1003, including startup refusals received before the UI subscribes. Reinstall the service and require service mode before reporting recovery.
This commit is contained in:
wonfen
2026-09-22 09:02:56 +08:00
parent 93b7bb8fe8
commit bffe91db5e
25 changed files with 105 additions and 11 deletions
+5
View File
@@ -62,6 +62,11 @@ pub fn take_service_fallback_notice() -> bool {
crate::core::service::take_service_fallback_notice()
}
#[tauri::command]
pub fn take_service_repair_notice() -> bool {
crate::core::service::take_service_repair_notice()
}
#[tauri::command]
pub fn sync_runtime_providers() {
if matches!(*CoreManager::global().get_running_mode(), RunningMode::Service) {
+11
View File
@@ -43,6 +43,7 @@ pub(crate) mod windows_fallback;
static OWNER_MONITOR_GENERATION: AtomicU64 = AtomicU64::new(0);
static ACTIVE_SERVICE_SESSION: Lazy<Mutex<Option<ActiveServiceSession>>> = Lazy::new(|| Mutex::new(None));
static PENDING_SERVICE_FALLBACK_NOTICE: AtomicBool = AtomicBool::new(false);
static PENDING_SERVICE_REPAIR_NOTICE: AtomicBool = AtomicBool::new(false);
#[cfg(target_os = "windows")]
pub(crate) fn notify_service_fallback() {
@@ -54,6 +55,10 @@ pub(crate) fn take_service_fallback_notice() -> bool {
PENDING_SERVICE_FALLBACK_NOTICE.swap(false, Ordering::Relaxed)
}
pub(crate) fn take_service_repair_notice() -> bool {
PENDING_SERVICE_REPAIR_NOTICE.swap(false, Ordering::Relaxed)
}
/// Capabilities of the service session that owns the running Core.
/// They are discarded with that session rather than cached across service upgrades.
#[derive(Clone)]
@@ -1153,6 +1158,11 @@ pub(super) async fn start_with_existing_service(config_file: &Path) -> Result<()
response.code,
err_msg
);
#[cfg(target_os = "windows")]
if response.code == ServiceErrorCode::InvalidInstallLocation as u16 {
PENDING_SERVICE_REPAIR_NOTICE.store(true, Ordering::Relaxed);
Handle::notice_message("service_core::repair_required", "");
}
start_owner_monitor();
return Err(ServiceStartRefusal {
code: response.code,
@@ -1179,6 +1189,7 @@ pub(super) async fn start_with_existing_service(config_file: &Path) -> Result<()
start_owner_monitor();
tracing::Span::current().record("outcome", "started");
PENDING_SERVICE_FALLBACK_NOTICE.store(false, Ordering::Relaxed);
PENDING_SERVICE_REPAIR_NOTICE.store(false, Ordering::Relaxed);
logging!(
info,
Type::Service,
+1
View File
@@ -171,6 +171,7 @@ mod app_init {
cmd::set_dns_override,
cmd::take_dns_override_notice,
cmd::take_service_fallback_notice,
cmd::take_service_repair_notice,
cmd::take_discarded_keys_notice,
cmd::get_dns_config_content,
cmd::validate_dns_config,