From e57854422a660b4397fe55b0c8ade9fac8cd2681 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Tue, 18 Jun 2024 22:04:34 +0800 Subject: [PATCH] fix kill main window in --server --- src/ipc.rs | 28 +++------------------------- src/server.rs | 23 ++++++++++++++++++----- 2 files changed, 21 insertions(+), 30 deletions(-) diff --git a/src/ipc.rs b/src/ipc.rs index 47cac05a6..5c926829c 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -699,6 +699,9 @@ async fn check_pid(postfix: &str) { } } } + // if not remove old ipc file, the new ipc creation will fail + // if we remove a ipc file, but the old ipc process is still running, + // new connection to the ipc will connect to new ipc, old connection to old ipc still keep alive std::fs::remove_file(&Config::ipc_path(postfix)).ok(); } @@ -985,31 +988,6 @@ pub async fn test_rendezvous_server() -> ResultType<()> { Ok(()) } -#[cfg(windows)] -pub fn is_ipc_file_exist(suffix: &str) -> ResultType { - // Not change this to std::path::Path::exists, unless it can be ensured that it can find the ipc which occupied by a process that taskkill can't kill. - let prefix = "\\\\.\\pipe\\"; - let file_name = Config::ipc_path(suffix).replace(prefix, ""); - let mut err = None; - for entry in std::fs::read_dir(prefix)? { - match entry { - Ok(entry) => { - if entry.file_name().into_string().unwrap_or_default() == file_name { - return Ok(true); - } - } - Err(e) => { - err = Some(e); - } - } - } - if let Some(e) = err { - Err(e.into()) - } else { - Ok(false) - } -} - #[tokio::main(flavor = "current_thread")] pub async fn send_url_scheme(url: String) -> ResultType<()> { connect(1_000, "_url") diff --git a/src/server.rs b/src/server.rs index 43edaea0e..e1f5d634c 100644 --- a/src/server.rs +++ b/src/server.rs @@ -467,12 +467,9 @@ pub async fn start_server(is_server: bool) { std::thread::spawn(move || { if let Err(err) = crate::ipc::start("") { log::error!("Failed to start ipc: {}", err); - #[cfg(windows)] - if crate::is_server() && crate::ipc::is_ipc_file_exist("").unwrap_or(false) { + if crate::is_server() { log::error!("ipc is occupied by another process, try kill it"); - if let Err(e) = crate::platform::try_kill_rustdesk_main_window_process() { - log::error!("kill failed: {}", e); - } + std::thread::spawn(stop_main_window_process).join().ok(); } std::process::exit(-1); } @@ -636,3 +633,19 @@ async fn sync_and_watch_config_dir() { } log::warn!("skipped config sync"); } + +#[tokio::main(flavor = "current_thread")] +pub async fn stop_main_window_process() { + // this may also kill another --server process, + // but --server usually can be auto restarted by --service, so it is ok + if let Ok(mut conn) = crate::ipc::connect(1000, "").await { + conn.send(&crate::ipc::Data::Close).await.ok(); + } + #[cfg(windows)] + { + // in case above failure, e.g. zombie process + if let Err(e) = crate::platform::try_kill_rustdesk_main_window_process() { + log::error!("kill failed: {}", e); + } + } +}