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");
crate::platform::uninstall_service(false);
} else if args[0] == "--service" {
#[cfg(target_os = "macos")]
crate::platform::macos::hide_dock();
log::info!("start --service");
crate::start_os_service();
return None;

View File

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

View File

@ -16,6 +16,8 @@
<key>AfterInitialDemand</key>
<false />
</dict>
<key>ThrottleInterval</key>
<integer>1</integer>
<key>RunAtLoad</key>
<true />
<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 synced = false;
let tries =
if std::env::args().len() == 2 && std::env::args().nth(1) == Some("--server".to_owned()) {
30
} else {
3
};
let is_server = std::env::args().nth(1) == Some("--server".to_owned());
let tries = if is_server { 30 } else { 3 };
log::debug!("#tries of ipc service connection: {}", tries);
use hbb_common::sleep;
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 {
Err(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;