mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-06-22 10:02:20 +00:00
Merge 3aca4274b5 into 2b40c61d8e
This commit is contained in:
commit
c8f623471f
3 changed files with 99 additions and 3 deletions
|
|
@ -48,6 +48,7 @@ class _DesktopHomePageState extends State<DesktopHomePage>
|
|||
var watchIsProcessTrust = false;
|
||||
var watchIsInputMonitoring = false;
|
||||
var watchIsCanRecordAudio = false;
|
||||
var watchIsInstalledDaemon = false;
|
||||
Timer? _updateTimer;
|
||||
bool isCardClosed = false;
|
||||
|
||||
|
|
@ -518,6 +519,14 @@ class _DesktopHomePageState extends State<DesktopHomePage>
|
|||
return Container();
|
||||
}
|
||||
final LinuxCards = <Widget>[];
|
||||
if (bind.mainIsInstalled() &&
|
||||
!bind.mainIsInstalledDaemon(prompt: false)) {
|
||||
LinuxCards.add(buildInstallCard(
|
||||
"", "install_daemon_tip", "Install", () async {
|
||||
bind.mainIsInstalledDaemon(prompt: true);
|
||||
watchIsInstalledDaemon = true;
|
||||
}, marginTop: LinuxCards.isEmpty ? 20.0 : 5.0));
|
||||
}
|
||||
if (bind.isSelinuxEnforcing()) {
|
||||
// Check is SELinux enforcing, but show user a tip of is SELinux enabled for simple.
|
||||
final keyShowSelinuxHelpTip = "show-selinux-help-tip";
|
||||
|
|
@ -731,6 +740,12 @@ class _DesktopHomePageState extends State<DesktopHomePage>
|
|||
setState(() {});
|
||||
}
|
||||
}
|
||||
if (watchIsInstalledDaemon) {
|
||||
if (bind.mainIsInstalledDaemon(prompt: false)) {
|
||||
watchIsInstalledDaemon = false;
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
if (watchIsCanRecordAudio) {
|
||||
if (isMacOS) {
|
||||
Future.microtask(() async {
|
||||
|
|
|
|||
|
|
@ -1999,6 +1999,69 @@ pub fn run_cmds_privileged(cmds: &str) -> bool {
|
|||
crate::platform::gtk_sudo::run(vec![cmds]).is_ok()
|
||||
}
|
||||
|
||||
/// Check whether the systemd service unit file is installed, or trigger installation.
|
||||
///
|
||||
/// - `prompt=false`: Returns `true` if the unit file exists in systemd's search paths.
|
||||
/// - `prompt=true`: Spawns a background thread that copies the unit file into
|
||||
/// `/etc/systemd/system/`, reloads systemd, enables and starts the service.
|
||||
/// Always returns `false` immediately (async, mirrors macOS behavior).
|
||||
pub fn is_installed_daemon(prompt: bool) -> bool {
|
||||
let app_name = crate::get_app_name().to_lowercase();
|
||||
let unit_name = format!("{app_name}.service");
|
||||
|
||||
if !prompt {
|
||||
return std::path::Path::new(&format!("/etc/systemd/system/{unit_name}")).exists()
|
||||
|| std::path::Path::new(&format!("/usr/lib/systemd/system/{unit_name}")).exists();
|
||||
}
|
||||
|
||||
// prompt=true: install the unit file in a background thread
|
||||
std::thread::spawn(move || {
|
||||
if let Err(e) = install_systemd_unit(&app_name, &unit_name) {
|
||||
log::error!("Failed to install systemd unit: {}", e);
|
||||
}
|
||||
});
|
||||
false
|
||||
}
|
||||
|
||||
/// Copy the systemd unit file to `/etc/systemd/system/`, reload, enable, and start.
|
||||
fn install_systemd_unit(app_name: &str, unit_name: &str) -> ResultType<()> {
|
||||
// Try to read the unit file from the package-installed path first
|
||||
let pkg_path = format!("/usr/share/{app_name}/files/systemd/{unit_name}");
|
||||
let unit_contents = if std::path::Path::new(&pkg_path).exists() {
|
||||
std::fs::read_to_string(&pkg_path)?
|
||||
} else {
|
||||
// Fall back to the embedded copy
|
||||
include_str!("../../res/rustdesk.service").to_string()
|
||||
};
|
||||
|
||||
// Fix pkill path to be absolute if /usr/bin/pkill exists
|
||||
let unit_contents = if std::path::Path::new("/usr/bin/pkill").exists() {
|
||||
unit_contents.replace("ExecStop=pkill ", "ExecStop=/usr/bin/pkill ")
|
||||
} else {
|
||||
unit_contents
|
||||
};
|
||||
|
||||
// Write to a temp file, then use privileged copy
|
||||
let tmp_path = format!("/tmp/.{unit_name}.tmp");
|
||||
std::fs::write(&tmp_path, &unit_contents)?;
|
||||
|
||||
let dst = format!("/etc/systemd/system/{unit_name}");
|
||||
let tmp_quoted = shell_quote(&tmp_path);
|
||||
let dst_quoted = shell_quote(&dst);
|
||||
|
||||
let success = run_cmds_privileged(&format!(
|
||||
"cp -f {tmp_quoted} {dst_quoted}; rm -f {tmp_quoted}; systemctl daemon-reload; systemctl enable {app_name}; systemctl start {app_name};"
|
||||
));
|
||||
|
||||
// Clean up temp file in case privileged command failed before removing it
|
||||
std::fs::remove_file(&tmp_path).ok();
|
||||
|
||||
if !success {
|
||||
bail!("Privileged command failed or was cancelled");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Spawn the current executable after a delay.
|
||||
///
|
||||
/// # Security
|
||||
|
|
@ -2063,9 +2126,17 @@ pub fn uninstall_service(show_new_window: bool, _: bool) -> bool {
|
|||
log::info!("Uninstalling service...");
|
||||
let cp = switch_service(true);
|
||||
let app_name = crate::get_app_name().to_lowercase();
|
||||
let unit_file = format!("/etc/systemd/system/{app_name}.service");
|
||||
// Remove admin-installed unit file (not package-owned /usr/lib/systemd/system/)
|
||||
let rm_unit = if std::path::Path::new(&unit_file).exists() {
|
||||
let quoted = shell_quote(&unit_file);
|
||||
format!("rm -f {quoted}; systemctl daemon-reload;")
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
// systemctl kill rustdesk --tray, execute cp first
|
||||
if !run_cmds_privileged(&format!(
|
||||
"{cp} systemctl disable {app_name}; systemctl stop {app_name};"
|
||||
"{cp} systemctl disable {app_name}; systemctl stop {app_name}; {rm_unit}"
|
||||
)) {
|
||||
Config::set_option("stop-service".into(), "".into());
|
||||
return true;
|
||||
|
|
@ -2085,7 +2156,15 @@ pub fn install_service() -> bool {
|
|||
log::info!("Installing service...");
|
||||
let cp = switch_service(false);
|
||||
let app_name = crate::get_app_name().to_lowercase();
|
||||
if !run_cmds_privileged(&format!(
|
||||
// If the unit file isn't installed yet, install it first
|
||||
if !is_installed_daemon(false) {
|
||||
let unit_name = format!("{app_name}.service");
|
||||
if let Err(e) = install_systemd_unit(&app_name, &unit_name) {
|
||||
log::error!("Failed to install systemd unit during service install: {}", e);
|
||||
Config::set_option("stop-service".into(), "Y".into());
|
||||
return true;
|
||||
}
|
||||
} else if !run_cmds_privileged(&format!(
|
||||
"{cp} systemctl enable {app_name}; systemctl start {app_name};"
|
||||
)) {
|
||||
Config::set_option("stop-service".into(), "Y".into());
|
||||
|
|
|
|||
|
|
@ -696,7 +696,9 @@ pub fn is_can_screen_recording(_prompt: bool) -> bool {
|
|||
pub fn is_installed_daemon(_prompt: bool) -> bool {
|
||||
#[cfg(target_os = "macos")]
|
||||
return crate::platform::macos::is_installed_daemon(_prompt);
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
#[cfg(target_os = "linux")]
|
||||
return crate::platform::linux::is_installed_daemon(_prompt);
|
||||
#[cfg(not(any(target_os = "macos", target_os = "linux")))]
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue