diff --git a/Cargo.toml b/Cargo.toml index ce0531b00d2..50caf433386 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -159,12 +159,10 @@ piet = "0.6" piet-coregraphics = "0.6" foreign-types = "0.3" -[target.'cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))'.dependencies] +[target.'cfg(any(target_os = "macos", target_os = "linux"))'.dependencies] tray-icon = { git = "https://github.com/tauri-apps/tray-icon", version = "0.21.3" } tao = { git = "https://github.com/rustdesk-org/tao", branch = "dev" } image = "0.24" - -[target.'cfg(any(target_os = "macos", target_os = "linux"))'.dependencies] keepawake = { git = "https://github.com/rustdesk-org/keepawake-rs" } [target.'cfg(any(target_os = "windows", target_os = "linux"))'.dependencies] diff --git a/res/msi/CustomActions/CustomActions.cpp b/res/msi/CustomActions/CustomActions.cpp index f4780dd876c..269d9d402d9 100644 --- a/res/msi/CustomActions/CustomActions.cpp +++ b/res/msi/CustomActions/CustomActions.cpp @@ -633,7 +633,7 @@ UINT __stdcall TryStopDeleteService(__in MSIHANDLE hInstall) // It's really strange that we need sleep here. // But the upgrading may be stuck at "copying new files" because the file is in using. - // Steps to reproduce: Install -> stop service in tray --> start service -> upgrade + // Steps to reproduce: Install -> stop service --> start service -> upgrade // Sleep(300); // Or we can terminate the process @@ -650,40 +650,6 @@ UINT __stdcall TryStopDeleteService(__in MSIHANDLE hInstall) return WcaFinalize(er); } -UINT __stdcall TryDeleteStartupShortcut(__in MSIHANDLE hInstall) -{ - HRESULT hr = S_OK; - DWORD er = ERROR_SUCCESS; - - wchar_t szShortcut[500] = { 0 }; - DWORD cchShortcut = sizeof(szShortcut) / sizeof(szShortcut[0]); - wchar_t szStartupDir[500] = { 0 }; - DWORD cchStartupDir = sizeof(szStartupDir) / sizeof(szStartupDir[0]); - WCHAR pwszTemp[1024] = L""; - - hr = WcaInitialize(hInstall, "DeleteStartupShortcut"); - ExitOnFailure(hr, "Failed to initialize"); - - MsiGetPropertyW(hInstall, L"StartupFolder", szStartupDir, &cchStartupDir); - - MsiGetPropertyW(hInstall, L"ShortcutName", szShortcut, &cchShortcut); - WcaLog(LOGMSG_STANDARD, "Try delete startup shortcut of : \"%ls\"", szShortcut); - - hr = StringCchPrintfW(pwszTemp, 1024, L"%ls%ls.lnk", szStartupDir, szShortcut); - ExitOnFailure(hr, "Failed to compose a resource identifier string"); - - if (DeleteFileW(pwszTemp)) { - WcaLog(LOGMSG_STANDARD, "Failed to delete startup shortcut of : \"%ls\"", pwszTemp); - } - else { - WcaLog(LOGMSG_STANDARD, "Startup shortcut is deleted : \"%ls\"", pwszTemp); - } - -LExit: - er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; - return WcaFinalize(er); -} - UINT __stdcall SetPropertyFromConfig(__in MSIHANDLE hInstall) { HRESULT hr = S_OK; diff --git a/res/msi/CustomActions/CustomActions.def b/res/msi/CustomActions/CustomActions.def index d50fbf59b33..43f01db48b2 100644 --- a/res/msi/CustomActions/CustomActions.def +++ b/res/msi/CustomActions/CustomActions.def @@ -8,7 +8,6 @@ EXPORTS SetPropertyIsServiceRunning TryStopDeleteService CreateStartService - TryDeleteStartupShortcut SetPropertyFromConfig AddRegSoftwareSASGeneration RemoveAmyuniIdd diff --git a/res/msi/Package/Components/RustDesk.wxs b/res/msi/Package/Components/RustDesk.wxs index 952172bdc9f..cd25ba19b7c 100644 --- a/res/msi/Package/Components/RustDesk.wxs +++ b/res/msi/Package/Components/RustDesk.wxs @@ -19,7 +19,6 @@ - @@ -28,7 +27,6 @@ - @@ -49,14 +47,9 @@ - - - - - - diff --git a/res/msi/Package/Fragments/AddRemoveProperties.wxs b/res/msi/Package/Fragments/AddRemoveProperties.wxs index ac1d85a86cc..9fc5248f384 100644 --- a/res/msi/Package/Fragments/AddRemoveProperties.wxs +++ b/res/msi/Package/Fragments/AddRemoveProperties.wxs @@ -9,8 +9,6 @@ - - - - - - diff --git a/src/core_main.rs b/src/core_main.rs index 2bd6c11b5fe..70adec72f24 100644 --- a/src/core_main.rs +++ b/src/core_main.rs @@ -79,18 +79,10 @@ pub fn core_main() -> Option> { } i += 1; } - #[cfg(any(target_os = "linux", target_os = "windows"))] + #[cfg(target_os = "linux")] if args.is_empty() { - #[cfg(target_os = "linux")] let should_check_start_tray = crate::check_process("--server", false); - // We can use `crate::check_process("--server", false)` on Windows. - // Because `--server` process is the System user's process. We can't get the arguments in `check_process()`. - // We can assume that self service running means the server is also running on Windows. - #[cfg(target_os = "windows")] - let should_check_start_tray = crate::platform::is_self_service_running() - && crate::platform::is_cur_exe_the_installed(); if should_check_start_tray && !crate::check_process("--tray", true) { - #[cfg(target_os = "linux")] hbb_common::allow_err!(crate::platform::check_autostart_config()); hbb_common::allow_err!(crate::run_me(vec!["--tray"])); } @@ -375,6 +367,7 @@ pub fn core_main() -> Option> { return None; } } else if args[0] == "--tray" { + #[cfg(not(target_os = "windows"))] if !crate::check_process("--tray", true) { crate::tray::start_tray(); } diff --git a/src/lib.rs b/src/lib.rs index 5621d5e2a68..932e776f04f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,7 +53,7 @@ mod port_forward; #[cfg(not(any(target_os = "android", target_os = "ios")))] pub mod plugin; -#[cfg(not(any(target_os = "android", target_os = "ios")))] +#[cfg(not(any(target_os = "android", target_os = "ios", target_os = "windows")))] mod tray; #[cfg(not(any(target_os = "android", target_os = "ios")))] diff --git a/src/platform/windows.rs b/src/platform/windows.rs index 1dc4a788a4d..b4303253482 100644 --- a/src/platform/windows.rs +++ b/src/platform/windows.rs @@ -1602,7 +1602,6 @@ oLink.Save .to_str() .unwrap_or("") .to_owned(); - let tray_shortcut = get_tray_shortcut(&path, &exe, &cur_exe, &tmp_path)?; let mut reg_value_desktop_shortcuts = "0".to_owned(); let mut reg_value_start_menu_shortcuts = "0".to_owned(); let mut reg_value_printer = "0".to_owned(); @@ -1645,7 +1644,6 @@ copy /Y \"{tmp_path}\\Uninstall {app_name}.lnk\" \"{start_menu}\\\" " if exist \"{mk_shortcut}\" del /f /q \"{mk_shortcut}\" if exist \"{uninstall_shortcut}\" del /f /q \"{uninstall_shortcut}\" -if exist \"{tray_shortcut}\" del /f /q \"{tray_shortcut}\" if exist \"{tmp_path}\\{app_name}.lnk\" del /f /q \"{tmp_path}\\{app_name}.lnk\" if exist \"{tmp_path}\\Uninstall {app_name}.lnk\" del /f /q \"{tmp_path}\\Uninstall {app_name}.lnk\" if exist \"{tmp_path}\\{app_name} Tray.lnk\" del /f /q \"{tmp_path}\\{app_name} Tray.lnk\" @@ -1660,15 +1658,6 @@ if exist \"{tmp_path}\\{app_name} Tray.lnk\" del /f /q \"{tmp_path}\\{app_name} Config::set_option("api-server".into(), lic.api); } - let tray_shortcuts = if config::is_outgoing_only() { - "".to_owned() - } else { - format!(" -cscript \"{tray_shortcut}\" -copy /Y \"{tmp_path}\\{app_name} Tray.lnk\" \"%PROGRAMDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\\" -") - }; - let install_remote_printer = if install_printer { // No need to use `|| true` here. // The script will not exit even if `--install-remote-printer` panics. @@ -1704,7 +1693,6 @@ reg add {subkey} /f /v EstimatedSize /t REG_DWORD /d {size} reg add {subkey} /f /v WindowsInstaller /t REG_DWORD /d 0 cscript \"{mk_shortcut}\" cscript \"{uninstall_shortcut}\" -{tray_shortcuts} {shortcuts} copy /Y \"{tmp_path}\\Uninstall {app_name}.lnk\" \"{path}\\\" {dels} @@ -3169,9 +3157,7 @@ pub fn uninstall_service(show_new_window: bool, _: bool) -> bool { pub fn install_service() -> bool { log::info!("Installing service..."); let _installing = crate::platform::InstallingService::new(); - let (_, path, _, exe) = get_install_info(); - let tmp_path = std::env::temp_dir().to_string_lossy().to_string(); - let tray_shortcut = get_tray_shortcut(&path, &exe, &exe, &tmp_path).unwrap_or_default(); + let (_, _, _, exe) = get_install_info(); let filter = format!(" /FI \"PID ne {}\"", get_current_pid()); Config::set_option("stop-service".into(), "".into()); crate::ipc::EXIT_RECV_CLOSE.store(false, Ordering::Relaxed); @@ -3179,11 +3165,8 @@ pub fn install_service() -> bool { " chcp 65001 taskkill /F /IM {app_name}.exe{filter} -cscript \"{tray_shortcut}\" -copy /Y \"{tmp_path}\\{app_name} Tray.lnk\" \"%PROGRAMDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\\" {import_config} {create_service} -if exist \"{tray_shortcut}\" del /f /q \"{tray_shortcut}\" ", app_name = crate::get_app_name(), import_config = get_import_config(&exe), @@ -3255,13 +3238,6 @@ pub fn update_me(debug: bool) -> ResultType<()> { .flatten() .collect::>(); kill_process_by_pids(&app_exe_name, main_window_pids)?; - let tray_pids = crate::platform::get_pids_of_process_with_args(&app_exe_name, &["--tray"]); - let tray_sessions = tray_pids - .iter() - .map(|pid| get_session_id_of_process(pid.as_u32())) - .flatten() - .collect::>(); - kill_process_by_pids(&app_exe_name, tray_pids)?; let is_service_running = is_self_service_running(); let mut version_major = "0"; @@ -3375,9 +3351,9 @@ reg add {subkey} /f /v EstimatedSize /t REG_DWORD /d {size} // // We need `taskkill` because: // 1. There may be some other processes like `rustdesk --connect` are running. - // 2. Sometimes, the main window and the tray icon are showing + // 2. Sometimes, the main window is showing // while I cannot find them by `tasklist` or the methods above. - // There's should be 4 processes running: service, server, tray and main window. + // There's should be 3 processes running: service, server and main window. // But only 2 processes are shown in the tasklist. let cmds = format!( " @@ -3404,35 +3380,6 @@ taskkill /F /IM {app_name}.exe{filter} b: true, f: Box::new(move || { let is_root = is_root(); - if tray_sessions.is_empty() { - log::info!("No tray process found."); - } else { - log::info!( - "Try to restore the tray process..., sessions: {:?}", - &tray_sessions - ); - // When not running as root, only spawn once since run_exe_direct - // doesn't target specific sessions. - let mut spawned_non_root_tray = false; - for s in tray_sessions.clone().into_iter() { - if s != 0 { - // We need to check if is_root here because if `update_me()` is called from - // the main window running with administrator permission, - // `run_exe_in_session()` will fail with error 1314 ("A required privilege is - // not held by the client"). - // - // This issue primarily affects the MSI-installed version running in Administrator - // session during testing, but we check permissions here to be safe. - if is_root { - allow_err!(run_exe_in_session(&exe, vec!["--tray"], s, true)); - } else if !spawned_non_root_tray { - // Only spawn once for non-root since run_exe_direct doesn't take session parameter - allow_err!(run_exe_direct(&exe, vec!["--tray"], false)); - spawned_non_root_tray = true; - } - } - } - } if main_window_sessions.is_empty() { log::info!("No main window process found."); } else { @@ -3619,54 +3566,24 @@ pub fn update_to(file: &str) -> ResultType<()> { Ok(()) } -// Don't launch tray app when running with `\qn`. -// 1. Because `/qn` requires administrator permission and the tray app should be launched with user permission. -// Or launching the main window from the tray app will cause the main window to be launched with administrator permission. -// 2. We are not able to launch the tray app if the UI is in the login screen. +// Don't launch the app when running with `\qn`. +// 1. Because `/qn` requires administrator permission and the app should be launched with user permission. +// 2. We are not able to launch the app if the UI is in the login screen. // `fn update_me()` can handle the above cases, but for msi update, we need to do more work to handle the above cases. -// 1. Record the tray app session ids. +// 1. Record the app session ids. // 2. Do the update. -// 3. Restore the tray app sessions. +// 3. Restore the app sessions. // `1` and `3` must be done in custom actions. -// We need also to handle the command line parsing to find the tray processes. +// We need also to handle the command line parsing to find the processes. pub fn update_me_msi(msi: &str, quiet: bool) -> ResultType<()> { let cmds = format!( "chcp 65001 && msiexec /i {msi} {}", - if quiet { "/qn LAUNCH_TRAY_APP=N" } else { "" } + if quiet { "/qn" } else { "" } ); run_cmds(cmds, false, "update-msi")?; Ok(()) } -pub fn get_tray_shortcut( - install_dir: &str, - exe: &str, - icon_source_exe: &str, - tmp_path: &str, -) -> ResultType { - let shortcut_icon_location = get_shortcut_icon_location(install_dir, icon_source_exe); - Ok(write_cmds( - format!( - " -Set oWS = WScript.CreateObject(\"WScript.Shell\") -sLinkFile = \"{tmp_path}\\{app_name} Tray.lnk\" - -Set oLink = oWS.CreateShortcut(sLinkFile) - oLink.TargetPath = \"{exe}\" - oLink.Arguments = \"--tray\" - {shortcut_icon_location} -oLink.Save - ", - app_name = crate::get_app_name(), - ), - "vbs", - "tray_shortcut", - )? - .to_str() - .unwrap_or("") - .to_owned()) -} - fn get_import_config(exe: &str) -> String { if config::is_outgoing_only() { return "".to_string(); @@ -3711,9 +3628,6 @@ fn run_after_run_cmds(silent: bool) { .creation_flags(winapi::um::winbase::CREATE_NO_WINDOW) .spawn()); } - if Config::get_option("stop-service") != "Y" { - allow_err!(std::process::Command::new(&exe).arg("--tray").spawn()); - } std::thread::sleep(std::time::Duration::from_millis(300)); } diff --git a/src/server/connection.rs b/src/server/connection.rs index 1ae9955777c..b4ca29db62c 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -2359,12 +2359,6 @@ impl Connection { } } }); - #[cfg(all(windows, feature = "flutter"))] - std::thread::spawn(move || { - if crate::is_server() && !crate::check_process("--tray", false) { - crate::platform::run_as_user(vec!["--tray"]).ok(); - } - }); } } diff --git a/src/tray.rs b/src/tray.rs index e8db0efc0b1..88963a5d794 100644 --- a/src/tray.rs +++ b/src/tray.rs @@ -1,12 +1,6 @@ use crate::client::translate; -#[cfg(windows)] -use crate::ipc::Data; -#[cfg(windows)] -use hbb_common::tokio; use hbb_common::{allow_err, log}; use std::sync::{Arc, Mutex}; -#[cfg(windows)] -use std::time::Duration; pub fn start_tray() { if crate::ui_interface::get_builtin_option(hbb_common::config::keys::OPTION_HIDE_TRAY) == "Y" { @@ -28,7 +22,7 @@ fn make_tray() -> hbb_common::ResultType<()> { use tao::event_loop::{ControlFlow, EventLoopBuilder}; use tray_icon::{ menu::{Menu, MenuEvent, MenuItem}, - TrayIcon, TrayIconBuilder, TrayIconEvent as TrayEvent, + TrayIcon, TrayIconBuilder, }; let icon; #[cfg(target_os = "macos")] @@ -89,9 +83,6 @@ fn make_tray() -> hbb_common::ResultType<()> { let mut _tray_icon: Arc>> = Default::default(); let menu_channel = MenuEvent::receiver(); - let tray_channel = TrayEvent::receiver(); - #[cfg(windows)] - let (ipc_sender, ipc_receiver) = std::sync::mpsc::channel::(); let open_func = move || { if cfg!(not(feature = "flutter")) { @@ -100,14 +91,6 @@ fn make_tray() -> hbb_common::ResultType<()> { } #[cfg(target_os = "macos")] crate::platform::macos::handle_application_should_open_untitled_file(); - #[cfg(target_os = "windows")] - { - // Do not use "start uni link" way, it may not work on some Windows, and pop out error - // dialog, I found on one user's desktop, but no idea why, Windows is shit. - // Use `run_me` instead. - // `allow_multiple_instances` in `flutter/windows/runner/main.cpp` allows only one instance without args. - crate::run_me::<&str>(vec![]).ok(); - } #[cfg(target_os = "linux")] { // Do not use "xdg-open", it won't read the config. @@ -119,12 +102,6 @@ fn make_tray() -> hbb_common::ResultType<()> { } }; - #[cfg(windows)] - std::thread::spawn(move || { - start_query_session_count(ipc_sender.clone()); - }); - #[cfg(windows)] - let mut last_click = std::time::Instant::now(); #[cfg(target_os = "macos")] { use tao::platform::macos::EventLoopExtMacOS; @@ -186,81 +163,9 @@ fn make_tray() -> hbb_common::ResultType<()> { open_func(); } } - - if let Ok(_event) = tray_channel.try_recv() { - #[cfg(target_os = "windows")] - match _event { - TrayEvent::Click { - button, - button_state, - .. - } => { - if button == tray_icon::MouseButton::Left - && button_state == tray_icon::MouseButtonState::Up - { - if last_click.elapsed() < std::time::Duration::from_secs(1) { - return; - } - open_func(); - last_click = std::time::Instant::now(); - } - } - _ => {} - } - } - - #[cfg(windows)] - if let Ok(data) = ipc_receiver.try_recv() { - match data { - Data::ControlledSessionCount(count) => { - _tray_icon - .lock() - .unwrap() - .as_mut() - .map(|t| t.set_tooltip(Some(tooltip(count)))); - } - _ => {} - } - } }); } -#[cfg(windows)] -#[tokio::main(flavor = "current_thread")] -async fn start_query_session_count(sender: std::sync::mpsc::Sender) { - let mut last_count = 0; - loop { - if let Ok(mut c) = crate::ipc::connect(1000, "").await { - let mut timer = crate::rustdesk_interval(tokio::time::interval(Duration::from_secs(1))); - loop { - tokio::select! { - res = c.next() => { - match res { - Err(err) => { - log::error!("ipc connection closed: {}", err); - break; - } - - Ok(Some(Data::ControlledSessionCount(count))) => { - if count != last_count { - last_count = count; - sender.send(Data::ControlledSessionCount(count)).ok(); - } - } - _ => {} - } - } - - _ = timer.tick() => { - c.send(&Data::ControlledSessionCount(0)).await.ok(); - } - } - } - } - hbb_common::sleep(1.).await; - } -} - fn load_icon_from_asset() -> Option { let Some(path) = std::env::current_exe().map_or(None, |x| x.parent().map(|x| x.to_path_buf())) else { @@ -268,8 +173,6 @@ fn load_icon_from_asset() -> Option { }; #[cfg(target_os = "macos")] let path = path.join("../Frameworks/App.framework/Resources/flutter_assets/assets/icon.png"); - #[cfg(windows)] - let path = path.join(r"data\flutter_assets\assets\icon.png"); #[cfg(target_os = "linux")] let path = path.join(r"data/flutter_assets/assets/icon.png"); if path.exists() {