This commit is contained in:
rustdesk 2024-03-26 22:31:58 +08:00
parent d407dfed0a
commit 81aec8402b
4 changed files with 80 additions and 45 deletions

View File

@ -267,8 +267,6 @@ pub fn core_main() -> Option<Vec<String>> {
log::info!("start --uninstall-service"); log::info!("start --uninstall-service");
crate::platform::uninstall_service(false); crate::platform::uninstall_service(false);
} else if args[0] == "--service" { } else if args[0] == "--service" {
#[cfg(target_os = "macos")]
crate::platform::macos::hide_dock();
log::info!("start --service"); log::info!("start --service");
crate::start_os_service(); crate::start_os_service();
return None; return None;

View File

@ -17,7 +17,7 @@ use core_graphics::{
display::{kCGNullWindowID, kCGWindowListOptionOnScreenOnly, CGWindowListCopyWindowInfo}, display::{kCGNullWindowID, kCGWindowListOptionOnScreenOnly, CGWindowListCopyWindowInfo},
window::{kCGWindowName, kCGWindowOwnerPID}, window::{kCGWindowName, kCGWindowOwnerPID},
}; };
use hbb_common::{allow_err, anyhow::anyhow, bail, log, message_proto::Resolution}; use hbb_common::{allow_err, anyhow::anyhow, bail, libc, log, message_proto::Resolution};
use include_dir::{include_dir, Dir}; use include_dir::{include_dir, Dir};
use objc::{class, msg_send, sel, sel_impl}; use objc::{class, msg_send, sel, sel_impl};
use scrap::{libc::c_void, quartz::ffi::*}; use scrap::{libc::c_void, quartz::ffi::*};
@ -479,38 +479,45 @@ pub fn lock_screen() {
} }
pub fn start_os_service() { pub fn start_os_service() {
crate::platform::macos::hide_dock();
let exe = std::env::current_exe().unwrap_or_default(); let exe = std::env::current_exe().unwrap_or_default();
let tm0 = hbb_common::get_modified_time(&exe); let tm0 = hbb_common::get_modified_time(&exe);
log::info!("{}", crate::username()); log::info!("Username: {}", crate::username());
log::info!("Startime: {:?}", get_server_start_time());
std::thread::spawn(move || loop { std::thread::spawn(move || loop {
loop { loop {
std::thread::sleep(std::time::Duration::from_millis(300)); std::thread::sleep(std::time::Duration::from_millis(300));
let now = hbb_common::get_modified_time(&exe); let now = hbb_common::get_modified_time(&exe);
if now != tm0 && now != std::time::UNIX_EPOCH { let file_updated = now != tm0 && now != std::time::UNIX_EPOCH;
let Some(start_time) = get_server_start_time() else {
continue;
};
let dt = start_time.1 - start_time.0;
if file_updated || dt >= 0 {
// sleep a while to wait for resources file ready // sleep a while to wait for resources file ready
std::thread::sleep(std::time::Duration::from_millis(300)); std::thread::sleep(std::time::Duration::from_millis(300));
println!("{:?} updated, will restart", exe); if file_updated {
// this won't kill myself log::info!("{:?} updated, will restart", exe);
std::process::Command::new("pkill") }
.args(&["-f", &crate::get_app_name()]) if dt >= 0 {
.status() // I tried add delegate (using tao and with its main loop0, but it works in normal mode, but not work as daemon
.ok(); log::info!(
println!("The others killed"); "Agent start later, {:?}, will restart to make delegate work",
// launchctl load/unload/start agent not work in daemon, show not privileged. start_time
// sudo launchctl asuser 501 open -n also not allowed. );
std::process::Command::new("launchctl") }
.args(&[ for pid in start_time.2 {
"asuser", unsafe {
&get_active_userid(), libc::kill(pid.as_u32() as _, libc::SIGTERM);
"open", }
"-a", }
&exe.to_str().unwrap_or(""), // https://emorydunn.github.io/LaunchAgent/Classes/LaunchAgent.html#/s:11LaunchAgentAAC16throttleIntervalSiSgvp,
"--args", // by default, ThrottleInterval = 10, we changed it to 1
"--server", if dt >= 0 {
]) std::thread::sleep(std::time::Duration::from_secs(dt.clamp(3, 30) as _));
.status() }
.ok(); log::info!("The others killed");
std::process::exit(0); std::process::exit(0);
} }
} }
@ -614,25 +621,50 @@ pub fn hide_dock() {
} }
} }
fn check_main_window() -> bool { fn get_server_start_time() -> Option<(i64, i64, Vec<hbb_common::sysinfo::Pid>)> {
if crate::check_process("", true) { use hbb_common::sysinfo::System;
return true; let mut sys = System::new();
sys.refresh_processes();
let mut path = std::env::current_exe().unwrap_or_default();
if let Ok(linked) = path.read_link() {
path = linked;
} }
let app = format!("/Applications/{}.app", crate::get_app_name()); let path = path.to_string_lossy().to_lowercase();
std::process::Command::new("open") let Some(my_start_time) = sys
.args(["-n", &app]) .process((std::process::id() as usize).into())
.status() .map(|p| p.start_time())
.ok(); else {
false return None;
};
let mut all = Vec::new();
for (_, p) in sys.processes() {
let mut cur_path = p.exe().to_path_buf();
if let Ok(linked) = cur_path.read_link() {
cur_path = linked;
}
if cur_path.to_string_lossy().to_lowercase() != path {
continue;
}
if p.pid().as_u32() == std::process::id() {
continue;
}
all.push(p);
}
for p in all.iter() {
let parg = if p.cmd().len() <= 1 { "" } else { &p.cmd()[1] };
let pids = all.iter().map(|p| p.pid()).collect();
if parg == "--server" {
return Some((my_start_time as _, p.start_time() as _, pids));
}
}
None
} }
pub fn handle_application_should_open_untitled_file() { pub fn handle_application_should_open_untitled_file() {
hbb_common::log::debug!("icon clicked on finder"); hbb_common::log::debug!("icon clicked on finder");
let x = std::env::args().nth(1).unwrap_or_default(); let x = std::env::args().nth(1).unwrap_or_default();
if x == "--server" || x == "--cm" || x == "--tray" { if x == "--server" || x == "--cm" || x == "--tray" {
if crate::platform::macos::check_main_window() { std::thread::spawn(move || crate::handle_url_scheme("".to_lowercase()));
allow_err!(crate::ipc::send_url_scheme(crate::get_uri_prefix()));
}
} }
} }

View File

@ -16,6 +16,8 @@
<key>AfterInitialDemand</key> <key>AfterInitialDemand</key>
<false /> <false />
</dict> </dict>
<key>ThrottleInterval</key>
<integer>1</integer>
<key>RunAtLoad</key> <key>RunAtLoad</key>
<true /> <true />
<key>ProgramArguments</key> <key>ProgramArguments</key>

View File

@ -550,12 +550,8 @@ async fn sync_and_watch_config_dir() {
let mut cfg0 = (Config::get(), Config2::get()); let mut cfg0 = (Config::get(), Config2::get());
let mut synced = false; let mut synced = false;
let tries = let is_server = std::env::args().nth(1) == Some("--server".to_owned());
if std::env::args().len() == 2 && std::env::args().nth(1) == Some("--server".to_owned()) { let tries = if is_server { 30 } else { 3 };
30
} else {
3
};
log::debug!("#tries of ipc service connection: {}", tries); log::debug!("#tries of ipc service connection: {}", tries);
use hbb_common::sleep; use hbb_common::sleep;
for i in 1..=tries { for i in 1..=tries {
@ -597,7 +593,14 @@ async fn sync_and_watch_config_dir() {
match conn.send(&Data::SyncConfig(Some(cfg.clone().into()))).await { match conn.send(&Data::SyncConfig(Some(cfg.clone().into()))).await {
Err(e) => { Err(e) => {
log::error!("sync config to root failed: {}", e); log::error!("sync config to root failed: {}", e);
break; match crate::ipc::connect(1000, "_service").await {
Ok(mut _conn) => {
conn = _conn;
log::info!("reconnected to ipc_service");
break;
}
_ => {}
}
} }
_ => { _ => {
cfg0 = cfg; cfg0 = cfg;