From a55be84795560346a4a415853ab52f0c08233325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=99=B4=E5=A4=A9?= Date: Mon, 9 Mar 2026 00:26:45 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20Gateway=20=E5=81=9C=E6=AD=A2=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=E6=97=A7=E7=89=88=E9=9A=90=E8=97=8F=E8=BF=9B=E7=A8=8B?= =?UTF-8?q?=EF=BC=8C=E6=8C=89=E7=AB=AF=E5=8F=A3=E6=9F=A5=E6=9D=80=E5=85=9C?= =?UTF-8?q?=E5=BA=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/commands/service.rs | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src-tauri/src/commands/service.rs b/src-tauri/src/commands/service.rs index 1d47b15..3140341 100644 --- a/src-tauri/src/commands/service.rs +++ b/src-tauri/src/commands/service.rs @@ -397,7 +397,7 @@ mod platform { Err("Gateway 启动超时,请检查终端窗口中的错误信息".into()) } - /// 关闭 Gateway 终端窗口 + /// 关闭 Gateway(兼容旧版隐藏进程和新版可见终端) pub async fn stop_service_impl(_label: &str) -> Result<(), String> { const CREATE_NO_WINDOW: u32 = 0x08000000; // 先尝试优雅停止 @@ -420,13 +420,33 @@ mod platform { } } - // 强制关闭终端窗口(会同时杀掉其中的 node 进程) + // 按窗口标题强杀(新版可见终端) let _ = TokioCommand::new("cmd") .args(["/c", "taskkill", "/f", "/fi", &format!("WINDOWTITLE eq {}", GATEWAY_WINDOW_TITLE)]) .creation_flags(CREATE_NO_WINDOW) .output() .await; + // 兜底:按端口查杀(兼容旧版隐藏进程) + if check_service_status(0, "").0 { + let port = read_gateway_port(); + let _ = kill_by_port(port).await; + } + + Ok(()) + } + + /// 通过 netstat 查找占用端口的 PID 并强制杀掉 + async fn kill_by_port(port: u16) -> Result<(), String> { + const CREATE_NO_WINDOW: u32 = 0x08000000; + let netstat_cmd = format!( + "for /f \"tokens=5\" %a in ('netstat -ano ^| findstr LISTENING ^| findstr :{port}') do taskkill /f /pid %a" + ); + let _ = TokioCommand::new("cmd") + .args(["/c", &netstat_cmd]) + .creation_flags(CREATE_NO_WINDOW) + .output() + .await; Ok(()) }