From 1ddbe7c2ccee8aef7802c9e495e992cfe783d044 Mon Sep 17 00:00:00 2001 From: Tunglies Date: Tue, 13 May 2025 01:56:19 +0800 Subject: [PATCH] feat: add service uninstall functionality and improve service operation flow --- UPDATELOG.md | 3 + src-tauri/src/cmd/clash.rs | 13 ++++ src-tauri/src/cmd/service.rs | 1 - src-tauri/src/lib.rs | 5 +- src/components/setting/setting-system.tsx | 89 ++++++++++++++++++----- src/services/cmds.ts | 8 ++ 6 files changed, 100 insertions(+), 19 deletions(-) diff --git a/UPDATELOG.md b/UPDATELOG.md index d1976d73..f706b370 100644 --- a/UPDATELOG.md +++ b/UPDATELOG.md @@ -39,6 +39,8 @@ - 更新依赖,替换弃用元素 - 首页当前节点增加排序功能 - DNS 覆写下增加 Hosts 设置功能 + - 修复服务模式安装后无法立即开启 TUN 模式的问题 + - 支持手动卸载服务模式,回退到 Sidecar 模式 #### 优化了: - 系统代理 Bypass 设置 @@ -54,6 +56,7 @@ - 重构通知系统 - 使用异步方法重构 UI 启动逻辑,解决启动软件过程中的各种卡死问题 - MacOS 下默认关闭托盘速率显示 + - 优化服务操作流程,提升系统服务相关操作的稳定性和用户体验 ## v2.2.3 diff --git a/src-tauri/src/cmd/clash.rs b/src-tauri/src/cmd/clash.rs index c790a350..23594e79 100644 --- a/src-tauri/src/cmd/clash.rs +++ b/src-tauri/src/cmd/clash.rs @@ -65,6 +65,19 @@ pub async fn change_clash_core(clash_core: String) -> CmdResult> } } +/// 启动核心 +#[tauri::command] +pub async fn start_core() -> CmdResult { + wrap_err!(CoreManager::global().start_core().await) +} + +/// 关闭核心 +#[tauri::command] +pub async fn stop_core() -> CmdResult { + wrap_err!(CoreManager::global().stop_core().await) +} + + /// 重启核心 #[tauri::command] pub async fn restart_core() -> CmdResult { diff --git a/src-tauri/src/cmd/service.rs b/src-tauri/src/cmd/service.rs index 96b9ff5f..c0f5b2fc 100644 --- a/src-tauri/src/cmd/service.rs +++ b/src-tauri/src/cmd/service.rs @@ -1,7 +1,6 @@ use super::CmdResult; use crate::{ core::{service, CoreManager}, - feat, utils::i18n::t, }; diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index ac01be12..0cffd99d 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -217,8 +217,11 @@ pub fn run() { cmd::get_portable_flag, cmd::get_network_interfaces, cmd::get_system_hostname, - cmd::restart_core, cmd::restart_app, + // 内核管理 + cmd::start_core, + cmd::stop_core, + cmd::restart_core, // 启动命令 cmd::notify_ui_ready, cmd::update_ui_stage, diff --git a/src/components/setting/setting-system.tsx b/src/components/setting/setting-system.tsx index 67ae3cdb..698e38d2 100644 --- a/src/components/setting/setting-system.tsx +++ b/src/components/setting/setting-system.tsx @@ -7,6 +7,7 @@ import { PauseRounded, WarningRounded, BuildRounded, + DeleteForeverRounded, } from "@mui/icons-material"; import { useVerge } from "@/hooks/use-verge"; import { DialogRef, Switch } from "@/components/base"; @@ -19,8 +20,10 @@ import { getSystemProxy, getAutotemProxy, installService, - getAutoLaunchStatus, + uninstallService, restartCore, + startCore, + stopCore, } from "@/services/cmds"; import { useLockFn } from "ahooks"; import { Button, Tooltip } from "@mui/material"; @@ -43,8 +46,6 @@ const SettingSystem = ({ onError }: Props) => { const { isAdminMode, isSidecarMode, mutateRunningMode, isServiceOk } = useSystemState(); - console.log("Is service running:", isServiceOk); - // 判断Tun模式是否可用 - 当处于服务模式或管理员模式时可用 const isTunAvailable = isServiceOk || (isSidecarMode && !isAdminMode); @@ -73,21 +74,60 @@ const SettingSystem = ({ onError }: Props) => { await mutate("getAutotemProxy"); }; - // 安装系统服务 - const onInstallService = useLockFn(async () => { - try { - showNotice("info", t("Installing Service..."), 1000); - await installService(); - showNotice("success", t("Service Installed Successfully"), 2000); - await restartCore(); - showNotice("info", t("Restarting Core"), 1000); - console.log("restartCore"); - // 重新获取运行模式 - await mutateRunningMode(); - } catch (err: any) { - showNotice("error", err.message || err.toString(), 3000); + // 抽象服务操作逻辑 + const handleServiceOperation = useLockFn( + async ( + { + beforeMsg, + action, + actionMsg, + successMsg, + }: { + beforeMsg: string; + action: () => Promise; + actionMsg: string; + successMsg: string; + } + ) => { + try { + showNotice("info", t(beforeMsg), 1000); + await stopCore(); + showNotice("info", t(actionMsg), 1000); + await action(); + showNotice("success", t(successMsg), 2000); + showNotice("info", t("Starting Core..."), 1000); + await startCore(); + await mutateRunningMode(); + } catch (err: any) { + showNotice("error", err.message || err.toString(), 3000); + try { + showNotice("info", t("Try running core as Sidecar..."), 1000); + await startCore(); + await mutateRunningMode(); + } catch (e: any) { + showNotice("error", e?.message || e?.toString(), 3000); + } + } } - }); + ); + + // 安装系统服务 + const onInstallService = () => + handleServiceOperation({ + beforeMsg: "Stopping Core...", + action: installService, + actionMsg: "Installing Service...", + successMsg: "Service Installed Successfully", + }); + + // 卸载系统服务 + const onUninstallService = () => + handleServiceOperation({ + beforeMsg: "Stopping Core...", + action: uninstallService, + actionMsg: "Uninstalling Service...", + successMsg: "Service Uninstalled Successfully", + }); return ( @@ -121,6 +161,21 @@ const SettingSystem = ({ onError }: Props) => { )} + { + isServiceOk && ( + + + + ) + } } > diff --git a/src/services/cmds.ts b/src/services/cmds.ts index a9e2d7a3..6c001118 100644 --- a/src/services/cmds.ts +++ b/src/services/cmds.ts @@ -131,6 +131,14 @@ export async function changeClashCore(clashCore: string) { return invoke("change_clash_core", { clashCore }); } +export async function startCore() { + return invoke("start_core"); +} + +export async function stopCore() { + return invoke("stop_core"); +} + export async function restartCore() { return invoke("restart_core"); }