diff --git a/Changelog.md b/Changelog.md
index 23d2922dc..3f3908a96 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -22,4 +22,8 @@
🚀 优化改进
+**🖥️ Windows**
+
+- 优化 Windows 服务安全检查未通过时的启动提示:显示具体原因,并提供修复文档链接
+
diff --git a/src-tauri/src/cmd/service.rs b/src-tauri/src/cmd/service.rs
index 50a5e0182..bf5aa4d85 100644
--- a/src-tauri/src/cmd/service.rs
+++ b/src-tauri/src/cmd/service.rs
@@ -113,7 +113,7 @@ pub async fn continue_with_sidecar() -> CmdResult {
}
#[tauri::command]
-pub fn take_service_fallback_notice() -> bool {
+pub fn take_service_fallback_notice() -> Option {
crate::core::service::take_service_fallback_notice()
}
diff --git a/src-tauri/src/core/manager/lifecycle.rs b/src-tauri/src/core/manager/lifecycle.rs
index d8c5784f2..1e2b43d82 100644
--- a/src-tauri/src/core/manager/lifecycle.rs
+++ b/src-tauri/src/core/manager/lifecycle.rs
@@ -678,7 +678,7 @@ impl CoreManager {
SERVICE_MANAGER.withdraw_sidecar_allowance();
self.rollback_failed_start().await;
} else {
- crate::core::service::notify_service_fallback();
+ crate::core::service::notify_service_fallback(&reason);
}
result.map_err(|error| error.context(format!("Service failure before Sidecar startup: {reason}")))
}
diff --git a/src-tauri/src/core/runstate/mod.rs b/src-tauri/src/core/runstate/mod.rs
index e06979ed5..bc1a9b4d8 100644
--- a/src-tauri/src/core/runstate/mod.rs
+++ b/src-tauri/src/core/runstate/mod.rs
@@ -28,7 +28,7 @@ pub use env::FakeEnv;
pub use env::{RealEnv, RunStateEnv};
pub use health::{PendingAction, RunState, RunStateView, ServiceHealth};
pub use owner::{OwnerRecoveryReason, OwnerSample, OwnerStep, OwnerWatch};
-pub use probe::{ServiceVersionCheck, ServiceVersionReply, classify_service_version_reply};
+pub use probe::{CORE_REJECTED_PREFIX, ServiceVersionCheck, ServiceVersionReply, classify_service_version_reply};
use crate::core::manager::RunningMode;
use health::StoredService;
diff --git a/src-tauri/src/core/runstate/probe.rs b/src-tauri/src/core/runstate/probe.rs
index 3fd6d95e7..93b284708 100644
--- a/src-tauri/src/core/runstate/probe.rs
+++ b/src-tauri/src/core/runstate/probe.rs
@@ -27,6 +27,9 @@ pub enum ServiceVersionCheck {
CoreUnavailable(String),
}
+/// Leads the Unavailable reason when the Service refused the approved core itself.
+pub const CORE_REJECTED_PREFIX: &str = "approved core was rejected: ";
+
/// What a live probe of the currently-installed Service told us.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CurrentServiceProbe {
@@ -47,7 +50,7 @@ pub fn classify_service_version_reply(reply: &ServiceVersionReply) -> ServiceVer
return match &reply.core {
Some(clash_verge_service_ipc::CoreAvailability::Ready) => ServiceVersionCheck::Ready,
Some(clash_verge_service_ipc::CoreAvailability::Rejected { reason }) => {
- ServiceVersionCheck::CoreUnavailable(format!("approved core was rejected: {reason}"))
+ ServiceVersionCheck::CoreUnavailable(format!("{CORE_REJECTED_PREFIX}{reason}"))
}
_ => ServiceVersionCheck::CoreUnavailable(
"the selected approved core is missing or does not match; reinstall the service to repair it".into(),
diff --git a/src-tauri/src/core/service.rs b/src-tauri/src/core/service.rs
index d61f8de1e..975ec597c 100644
--- a/src-tauri/src/core/service.rs
+++ b/src-tauri/src/core/service.rs
@@ -9,8 +9,8 @@ use crate::{
owner_identity::current_owner_credentials,
proxy_control,
runstate::{
- OwnerRecoveryReason, OwnerSample, OwnerStep, OwnerWatch, PendingAction, RUN_STATE, ReadyWaitError,
- RunState, RunStateEnv, RunStateStore, ServiceHealth,
+ CORE_REJECTED_PREFIX, OwnerRecoveryReason, OwnerSample, OwnerStep, OwnerWatch, PendingAction, RUN_STATE,
+ ReadyWaitError, RunState, RunStateEnv, RunStateStore, ServiceHealth,
},
runtime_bundle::{RemoteProviderRef, collect_runtime_bundle, remote_providers_of},
tray::Tray,
@@ -39,18 +39,31 @@ use std::{
static OWNER_MONITOR_GENERATION: AtomicU64 = AtomicU64::new(0);
static ACTIVE_SERVICE_SESSION: Lazy>> = Lazy::new(|| Mutex::new(None));
-static PENDING_SERVICE_FALLBACK_NOTICE: AtomicBool = AtomicBool::new(false);
+static PENDING_SERVICE_FALLBACK_NOTICE: Mutex