From b07ac438f5de092c9bd980f841856b65f8e42e45 Mon Sep 17 00:00:00 2001 From: rustdesk Date: Mon, 5 Jun 2023 20:27:48 +0800 Subject: [PATCH] working on windows service install/uninstall --- Cargo.lock | 427 ++----------------- Cargo.toml | 10 +- build.rs | 2 +- flutter/macos/Runner/MainFlutterWindow.swift | 2 +- flutter/windows/runner/CMakeLists.txt | 7 + flutter/windows/runner/Runner.rc | 10 +- flutter/windows/runner/main.cpp | 2 +- libs/portable/Cargo.toml | 1 + libs/portable/icon.rc | 2 +- libs/portable/src/bin_reader.rs | 16 +- libs/portable/src/main.rs | 11 +- res/icon.ico | 1 - src/core_main.rs | 3 - src/lib.rs | 2 - src/platform/windows.rs | 298 +++++++------ src/tray.rs | 124 ++---- src/ui_interface.rs | 50 +-- 17 files changed, 280 insertions(+), 688 deletions(-) delete mode 120000 res/icon.ico diff --git a/Cargo.lock b/Cargo.lock index bec83b664..7d347efeb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -195,14 +195,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6041616acea41d67c4a984709ddab1587fd0b10efe5cc563fee954d2f011854" dependencies = [ "clipboard-win", - "core-graphics 0.22.3", + "core-graphics", "image", "log", "objc", "objc-foundation", "objc_id", "once_cell", - "parking_lot 0.12.1", + "parking_lot", "thiserror", "winapi 0.3.9", "x11rb", @@ -642,16 +642,6 @@ dependencies = [ "system-deps 6.1.0", ] -[[package]] -name = "calloop" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf2eec61efe56aa1e813f5126959296933cf0700030e4314786c48779a66ab82" -dependencies = [ - "log", - "nix 0.22.3", -] - [[package]] name = "camino" version = "1.1.4" @@ -927,8 +917,8 @@ dependencies = [ "bitflags", "block", "cocoa-foundation", - "core-foundation 0.9.3", - "core-graphics 0.22.3", + "core-foundation", + "core-graphics", "foreign-types", "libc", "objc", @@ -942,7 +932,7 @@ checksum = "931d3837c286f56e3c58423ce4eba12d08db2374461a785c86f672b08b5650d6" dependencies = [ "bitflags", "block", - "core-foundation 0.9.3", + "core-foundation", "core-graphics-types", "foreign-types", "libc", @@ -1034,16 +1024,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb4a24b1aaf0fd0ce8b45161144d6f42cd91677fd5940fd431183eb023b3a2b8" -[[package]] -name = "core-foundation" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" -dependencies = [ - "core-foundation-sys 0.7.0", - "libc", -] - [[package]] name = "core-foundation" version = "0.9.3" @@ -1060,30 +1040,12 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" -[[package]] -name = "core-foundation-sys" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" - [[package]] name = "core-foundation-sys" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" -[[package]] -name = "core-graphics" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3889374e6ea6ab25dba90bb5d96202f61108058361f6dc72e8b03e6f8bbe923" -dependencies = [ - "bitflags", - "core-foundation 0.7.0", - "foreign-types", - "libc", -] - [[package]] name = "core-graphics" version = "0.22.3" @@ -1091,7 +1053,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" dependencies = [ "bitflags", - "core-foundation 0.9.3", + "core-foundation", "core-graphics-types", "foreign-types", "libc", @@ -1104,24 +1066,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" dependencies = [ "bitflags", - "core-foundation 0.9.3", + "core-foundation", "foreign-types", "libc", ] -[[package]] -name = "core-video-sys" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ecad23610ad9757664d644e369246edde1803fcb43ed72876565098a5d3828" -dependencies = [ - "cfg-if 0.1.10", - "core-foundation-sys 0.7.0", - "core-graphics 0.19.2", - "libc", - "objc", -] - [[package]] name = "coreaudio-rs" version = "0.11.2" @@ -1160,7 +1109,7 @@ dependencies = [ "ndk-context", "oboe", "once_cell", - "parking_lot 0.12.1", + "parking_lot", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -1264,12 +1213,6 @@ dependencies = [ "windows-sys 0.45.0", ] -[[package]] -name = "cty" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" - [[package]] name = "cxx" version = "1.0.94" @@ -1331,41 +1274,6 @@ dependencies = [ "zvariant", ] -[[package]] -name = "darling" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2 1.0.56", - "quote 1.0.27", - "strsim 0.10.0", - "syn 1.0.109", -] - -[[package]] -name = "darling_macro" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" -dependencies = [ - "darling_core", - "quote 1.0.27", - "syn 1.0.109", -] - [[package]] name = "dart-sys" version = "4.0.2" @@ -1670,15 +1578,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" -[[package]] -name = "dlib" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1b7517328c04c2aa68422fc60a41b92208182142ed04a25879c26c8f878794" -dependencies = [ - "libloading 0.7.4", -] - [[package]] name = "dlopen" version = "0.1.8" @@ -1743,12 +1642,6 @@ dependencies = [ "strsim 0.10.0", ] -[[package]] -name = "downcast-rs" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" - [[package]] name = "dtoa" version = "0.4.8" @@ -1808,7 +1701,7 @@ dependencies = [ name = "enigo" version = "0.0.14" dependencies = [ - "core-graphics 0.22.3", + "core-graphics", "hbb_common", "log", "objc", @@ -2104,7 +1997,7 @@ dependencies = [ "lazy_static", "libc", "log", - "parking_lot 0.12.1", + "parking_lot", "threadpool", "wasm-bindgen", "web-sys", @@ -3046,12 +2939,6 @@ dependencies = [ "cxx-build", ] -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "idna" version = "0.3.0" @@ -3145,9 +3032,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if 1.0.0", - "js-sys", - "wasm-bindgen", - "web-sys", ] [[package]] @@ -3592,15 +3476,6 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" -[[package]] -name = "memmap2" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b6c2ebff6180198788f5db08d7ce3bc1d0b617176678831a7510825973e357" -dependencies = [ - "libc", -] - [[package]] name = "memoffset" version = "0.6.5" @@ -3723,19 +3598,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "ndk" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d868f654c72e75f8687572699cdabe755f03effbb62542768e995d5b8d699d" -dependencies = [ - "bitflags", - "jni-sys", - "ndk-sys 0.2.2", - "num_enum", - "thiserror", -] - [[package]] name = "ndk" version = "0.6.0" @@ -3759,7 +3621,7 @@ dependencies = [ "jni-sys", "ndk-sys 0.4.1+23.1.7779620", "num_enum", - "raw-window-handle 0.5.2", + "raw-window-handle", "thiserror", ] @@ -3769,40 +3631,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" -[[package]] -name = "ndk-glue" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c71bee8ea72d685477e28bd004cfe1bf99c754d688cd78cad139eae4089484d4" -dependencies = [ - "lazy_static", - "libc", - "log", - "ndk 0.5.0", - "ndk-context", - "ndk-macro", - "ndk-sys 0.2.2", -] - -[[package]] -name = "ndk-macro" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0df7ac00c4672f9d5aece54ee3347520b7e20f158656c7db2e6de01902eb7a6c" -dependencies = [ - "darling", - "proc-macro-crate 1.3.1", - "proc-macro2 1.0.56", - "quote 1.0.27", - "syn 1.0.109", -] - -[[package]] -name = "ndk-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1bcdd74c20ad5d95aacd60ef9ba40fdf77f767051040541df557b7a9b2a2121" - [[package]] name = "ndk-sys" version = "0.3.0" @@ -3870,19 +3698,6 @@ dependencies = [ "log", ] -[[package]] -name = "nix" -version = "0.22.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4916f159ed8e5de0082076562152a76b7a1f64a01fd9d1e0fea002c37624faf" -dependencies = [ - "bitflags", - "cc", - "cfg-if 1.0.0", - "libc", - "memoffset 0.6.5", -] - [[package]] name = "nix" version = "0.23.2" @@ -4290,17 +4105,6 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - [[package]] name = "parking_lot" version = "0.12.1" @@ -4308,21 +4112,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.7", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if 1.0.0", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi 0.3.9", + "parking_lot_core", ] [[package]] @@ -4889,15 +4679,6 @@ dependencies = [ "rand_core 0.3.1", ] -[[package]] -name = "raw-window-handle" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b800beb9b6e7d2df1fe337c9e3d04e3af22a124460fb4c30fcc22c9117cefb41" -dependencies = [ - "cty", -] - [[package]] name = "raw-window-handle" version = "0.5.2" @@ -4932,9 +4713,9 @@ version = "0.5.0-2" source = "git+https://github.com/fufesou/rdev#f43a42fbedf1234a4bc132581790d63c9a2c8f92" dependencies = [ "cocoa", - "core-foundation 0.9.3", + "core-foundation", "core-foundation-sys 0.8.4", - "core-graphics 0.22.3", + "core-graphics", "dispatch", "enum-map", "epoll", @@ -5197,8 +4978,8 @@ dependencies = [ "clap 4.2.7", "clipboard", "cocoa", - "core-foundation 0.9.3", - "core-graphics 0.22.3", + "core-foundation", + "core-graphics", "cpal", "crossbeam-queue", "ctrlc", @@ -5258,7 +5039,6 @@ dependencies = [ "system_shutdown", "tao", "tray-icon", - "trayicon", "url", "users 0.11.0", "uuid", @@ -5266,7 +5046,6 @@ dependencies = [ "whoami", "winapi 0.3.9", "windows-service", - "winit", "winreg 0.10.1", "winres", "wol-rs", @@ -5281,6 +5060,7 @@ dependencies = [ "dirs 5.0.1", "embed-resource", "md5", + "winapi 0.3.9", ] [[package]] @@ -5401,12 +5181,6 @@ dependencies = [ "objc-foundation", ] -[[package]] -name = "scoped-tls" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" - [[package]] name = "scopeguard" version = "1.1.0" @@ -5467,7 +5241,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" dependencies = [ "bitflags", - "core-foundation 0.9.3", + "core-foundation", "core-foundation-sys 0.8.4", "libc", "security-framework-sys", @@ -5684,25 +5458,6 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" -[[package]] -name = "smithay-client-toolkit" -version = "0.15.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a28f16a97fa0e8ce563b2774d1e732dd5d4025d2772c5dba0a41a0f90a29da3" -dependencies = [ - "bitflags", - "calloop", - "dlib", - "lazy_static", - "log", - "memmap2", - "nix 0.22.3", - "pkg-config", - "wayland-client", - "wayland-cursor", - "wayland-protocols", -] - [[package]] name = "socket2" version = "0.3.19" @@ -5889,7 +5644,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d75182f12f490e953596550b65ee31bda7c8e043d9386174b353bda50838c3fd" dependencies = [ "bitflags", - "core-foundation 0.9.3", + "core-foundation", "system-configuration-sys", ] @@ -5950,8 +5705,8 @@ dependencies = [ "cairo-rs", "cc", "cocoa", - "core-foundation 0.9.3", - "core-graphics 0.22.3", + "core-foundation", + "core-graphics", "crossbeam-channel", "dispatch", "gdk", @@ -5974,9 +5729,9 @@ dependencies = [ "ndk-sys 0.3.0", "objc", "once_cell", - "parking_lot 0.12.1", + "parking_lot", "png", - "raw-window-handle 0.5.2", + "raw-window-handle", "scopeguard", "tao-macros", "unicode-segmentation", @@ -6071,7 +5826,7 @@ version = "0.6.1" source = "git+https://github.com/fufesou/The-Fat-Controller#9dd86151525fd010dc93f6bc9b6aedd1a75cc342" dependencies = [ "anyhow", - "core-graphics 0.22.3", + "core-graphics", "unicode-segmentation", "winapi 0.3.9", "x11 2.19.0", @@ -6181,7 +5936,7 @@ dependencies = [ "libc", "mio", "num_cpus", - "parking_lot 0.12.1", + "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2 0.4.9", @@ -6349,7 +6104,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0a1ba93b51da357afb4064093d925ded565154aca52f60d5a088b826150d7a8" dependencies = [ "cocoa", - "core-graphics 0.22.3", + "core-graphics", "crossbeam-channel", "dirs-next", "libappindicator", @@ -6361,15 +6116,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "trayicon" -version = "0.1.3-1" -source = "git+https://github.com/open-trade/trayicon-rs#35bd01963271b45a0b6a0f65f1ce03a5f35bc691" -dependencies = [ - "winapi 0.3.9", - "winit", -] - [[package]] name = "try-lock" version = "0.2.4" @@ -6649,79 +6395,6 @@ version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a901d592cafaa4d711bc324edfaff879ac700b19c3dfd60058d2b445be2691eb" -[[package]] -name = "wayland-client" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715" -dependencies = [ - "bitflags", - "downcast-rs", - "libc", - "nix 0.24.3", - "scoped-tls", - "wayland-commons", - "wayland-scanner", - "wayland-sys", -] - -[[package]] -name = "wayland-commons" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902" -dependencies = [ - "nix 0.24.3", - "once_cell", - "smallvec", - "wayland-sys", -] - -[[package]] -name = "wayland-cursor" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661" -dependencies = [ - "nix 0.24.3", - "wayland-client", - "xcursor", -] - -[[package]] -name = "wayland-protocols" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6" -dependencies = [ - "bitflags", - "wayland-client", - "wayland-commons", - "wayland-scanner", -] - -[[package]] -name = "wayland-scanner" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53" -dependencies = [ - "proc-macro2 1.0.56", - "quote 1.0.27", - "xml-rs", -] - -[[package]] -name = "wayland-sys" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4" -dependencies = [ - "dlib", - "lazy_static", - "pkg-config", -] - [[package]] name = "web-sys" version = "0.3.62" @@ -7158,39 +6831,6 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" -[[package]] -name = "winit" -version = "0.26.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b43cc931d58b99461188607efd7acb2a093e65fc621f54cad78517a6063e73a" -dependencies = [ - "bitflags", - "cocoa", - "core-foundation 0.9.3", - "core-graphics 0.22.3", - "core-video-sys", - "dispatch", - "instant", - "lazy_static", - "libc", - "log", - "mio", - "ndk 0.5.0", - "ndk-glue", - "ndk-sys 0.2.2", - "objc", - "parking_lot 0.11.2", - "percent-encoding", - "raw-window-handle 0.4.3", - "smithay-client-toolkit", - "wasm-bindgen", - "wayland-client", - "wayland-protocols", - "web-sys", - "winapi 0.3.9", - "x11-dl", -] - [[package]] name = "winnow" version = "0.4.6" @@ -7295,15 +6935,6 @@ dependencies = [ "nix 0.24.3", ] -[[package]] -name = "xcursor" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7" -dependencies = [ - "nom", -] - [[package]] name = "xdg-home" version = "1.0.0" @@ -7314,12 +6945,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "xml-rs" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1fcc45bb67e8bd9c33ada4b861bccfe2506e726169f7c1081b95841b3758eb3" - [[package]] name = "yaml-rust" version = "0.4.5" diff --git a/Cargo.toml b/Cargo.toml index 9c0834ee5..7a3d73b1b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,6 @@ path = "src/naming.rs" [features] inline = [] -hbbs = [] cli = [] flutter_texture_render = [] appimage = [] @@ -92,9 +91,7 @@ arboard = "3.2" system_shutdown = "4.0" [target.'cfg(target_os = "windows")'.dependencies] -trayicon = { git = "https://github.com/open-trade/trayicon-rs", features = ["winit"] } -winit = "0.26" -winapi = { version = "0.3", features = ["winuser", "wincrypt"] } +winapi = { version = "0.3", features = ["winuser", "wincrypt", "shellscalingapi"] } winreg = "0.10" windows-service = "0.6" virtual_display = { path = "libs/virtual_display", optional = true } @@ -113,7 +110,7 @@ dark-light = "1.0" fruitbasket = "0.10" objc_id = "0.1" -[target.'cfg(any(target_os = "macos", target_os = "linux"))'.dependencies] +[target.'cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))'.dependencies] tray-icon = "0.5" tao = { git = "https://github.com/Kingtous/tao", branch = "muda" } image = "0.24" @@ -134,9 +131,6 @@ users = { version = "0.11" } android_logger = "0.13" jni = "0.21" -[target.'cfg(any(target_os = "android", target_os = "ios"))'.dependencies] -flutter_rust_bridge = "1.75" - [workspace] members = ["libs/scrap", "libs/hbb_common", "libs/enigo", "libs/clipboard", "libs/virtual_display", "libs/virtual_display/dylib", "libs/portable"] exclude = ["vdi/host", "examples/custom_plugin"] diff --git a/build.rs b/build.rs index 7ff8f9ef6..1ffc102fe 100644 --- a/build.rs +++ b/build.rs @@ -25,7 +25,7 @@ fn build_manifest() { use std::io::Write; if std::env::var("PROFILE").unwrap() == "release" { let mut res = winres::WindowsResource::new(); - res.set_icon("res/icon.ico") + res.set_icon("res/tray-icon.ico") .set_language(winapi::um::winnt::MAKELANGID( winapi::um::winnt::LANG_ENGLISH, winapi::um::winnt::SUBLANG_ENGLISH_US, diff --git a/flutter/macos/Runner/MainFlutterWindow.swift b/flutter/macos/Runner/MainFlutterWindow.swift index 9daaeee21..1c9e361f3 100644 --- a/flutter/macos/Runner/MainFlutterWindow.swift +++ b/flutter/macos/Runner/MainFlutterWindow.swift @@ -22,7 +22,7 @@ import texture_rgba_renderer class MainFlutterWindow: NSWindow { override func awakeFromNib() { if (!rustdesk_core_main()){ - print("Rustdesk core returns false, exiting without launching Flutter app.") + // print("Rustdesk core returns false, exiting without launching Flutter app.") NSApplication.shared.terminate(self) } let flutterViewController = FlutterViewController.init() diff --git a/flutter/windows/runner/CMakeLists.txt b/flutter/windows/runner/CMakeLists.txt index b9e550fba..17411a8ab 100644 --- a/flutter/windows/runner/CMakeLists.txt +++ b/flutter/windows/runner/CMakeLists.txt @@ -20,6 +20,13 @@ add_executable(${BINARY_NAME} WIN32 # that need different build settings. apply_standard_settings(${BINARY_NAME}) +# Add preprocessor definitions for the build version. +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") + # Disable Windows macros that collide with C++ standard library functions. target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") diff --git a/flutter/windows/runner/Runner.rc b/flutter/windows/runner/Runner.rc index db0b44e23..32d01bf44 100644 --- a/flutter/windows/runner/Runner.rc +++ b/flutter/windows/runner/Runner.rc @@ -60,14 +60,14 @@ IDI_APP_ICON ICON "resources\\app_icon.ico" // Version // -#ifdef FLUTTER_BUILD_NUMBER -#define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER +#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD) +#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD #else -#define VERSION_AS_NUMBER 1,0,0 +#define VERSION_AS_NUMBER 1,0,0,0 #endif -#ifdef FLUTTER_BUILD_NAME -#define VERSION_AS_STRING #FLUTTER_BUILD_NAME +#if defined(FLUTTER_VERSION) +#define VERSION_AS_STRING FLUTTER_VERSION #else #define VERSION_AS_STRING "1.0.0" #endif diff --git a/flutter/windows/runner/main.cpp b/flutter/windows/runner/main.cpp index ae8e1d834..6f3afe1d9 100644 --- a/flutter/windows/runner/main.cpp +++ b/flutter/windows/runner/main.cpp @@ -54,7 +54,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, for (const auto& argument : command_line_arguments) { args_str += (argument + " "); } - std::cout << "Rustdesk [" << args_str << "], core returns false, exiting without launching Flutter app." << std::endl; + // std::cout << "Rustdesk [" << args_str << "], core returns false, exiting without launching Flutter app." << std::endl; return EXIT_SUCCESS; } std::vector rust_args(c_args, c_args + args_len); diff --git a/libs/portable/Cargo.toml b/libs/portable/Cargo.toml index a63c5aad3..f51197cdb 100644 --- a/libs/portable/Cargo.toml +++ b/libs/portable/Cargo.toml @@ -14,3 +14,4 @@ embed-resource = "2.1" brotli = "3.3" dirs = "5.0" md5 = "0.7" +winapi = { version = "0.3", features = ["winbase"] } diff --git a/libs/portable/icon.rc b/libs/portable/icon.rc index 2f41e79d8..96fdf0b6e 100644 --- a/libs/portable/icon.rc +++ b/libs/portable/icon.rc @@ -1 +1 @@ -rustdesk_icon ICON "../../res/icon.ico" \ No newline at end of file +rustdesk_icon ICON "../../res/tray-icon.ico" \ No newline at end of file diff --git a/libs/portable/src/bin_reader.rs b/libs/portable/src/bin_reader.rs index 0a6cd8ef9..ced5baf32 100644 --- a/libs/portable/src/bin_reader.rs +++ b/libs/portable/src/bin_reader.rs @@ -38,7 +38,7 @@ impl BinaryData { let cursor = Cursor::new(self.raw); let mut decoder = brotli::Decompressor::new(cursor, BUF_SIZE); let mut buf = Vec::new(); - decoder.read_to_end(&mut buf).unwrap(); + decoder.read_to_end(&mut buf).ok(); buf } @@ -51,7 +51,7 @@ impl BinaryData { } if p.exists() { // check md5 - let f = fs::read(p.clone()).unwrap(); + let f = fs::read(p.clone()).unwrap_or_default(); let digest = format!("{:x}", md5::compute(&f)); let md5_record = String::from_utf8_lossy(self.md5_code); if digest == md5_record { @@ -127,11 +127,13 @@ impl BinaryReader { let exe_path = prefix.join(&self.exe); if exe_path.exists() { - let f = File::open(exe_path).unwrap(); - let meta = f.metadata().unwrap(); - let mut permissions = meta.permissions(); - permissions.set_mode(0o755); - f.set_permissions(permissions).unwrap(); + if let Ok(f) = File::open(exe_path) { + if let Ok(meta) = f.metadata() { + let mut permissions = meta.permissions(); + permissions.set_mode(0o755); + f.set_permissions(permissions).ok(); + } + } } } } diff --git a/libs/portable/src/main.rs b/libs/portable/src/main.rs index ca335363f..7f7743d17 100644 --- a/libs/portable/src/main.rs +++ b/libs/portable/src/main.rs @@ -1,6 +1,7 @@ #![windows_subsystem = "windows"] use std::{ + os::windows::process::CommandExt, path::PathBuf, process::{Command, Stdio}, }; @@ -40,17 +41,18 @@ fn setup(reader: BinaryReader, dir: Option, clear: bool) -> Option) { println!("executing {}", path.display()); // setup env - let exe = std::env::current_exe().unwrap(); - let exe_name = exe.file_name().unwrap(); + let exe = std::env::current_exe().unwrap_or_default(); + let exe_name = exe.file_name().unwrap_or_default(); // run executable Command::new(path) .args(args) + .creation_flags(winapi::um::winbase::CREATE_NO_WINDOW) .env(APPNAME_RUNTIME_ENV_KEY, exe_name) .stdin(Stdio::inherit()) .stdout(Stdio::inherit()) .stderr(Stdio::inherit()) .output() - .expect(&format!("failed to execute {:?}", exe_name)); + .ok(); } fn main() { @@ -84,7 +86,7 @@ fn main() { } mod windows { - use std::{fs, path::PathBuf, process::Command}; + use std::{fs, os::windows::process::CommandExt, path::PathBuf, process::Command}; // Used for privacy mode(magnifier impl). pub const RUNTIME_BROKER_EXE: &'static str = "C:\\Windows\\System32\\RuntimeBroker.exe"; @@ -105,6 +107,7 @@ mod windows { } let _allow_err = Command::new("taskkill") .args(&["/F", "/IM", "RuntimeBroker_rustdesk.exe"]) + .creation_flags(winapi::um::winbase::CREATE_NO_WINDOW) .output(); let _allow_err = std::fs::copy(src, &format!("{}\\{}", dir.to_string_lossy(), tgt)); } diff --git a/res/icon.ico b/res/icon.ico deleted file mode 120000 index 75324b38c..000000000 --- a/res/icon.ico +++ /dev/null @@ -1 +0,0 @@ -../flutter/windows/runner/resources/app_icon.ico \ No newline at end of file diff --git a/src/core_main.rs b/src/core_main.rs index 2b2467729..13cf62fcd 100644 --- a/src/core_main.rs +++ b/src/core_main.rs @@ -127,9 +127,6 @@ pub fn core_main() -> Option> { log::error!("Failed to before-uninstall: {}", err); } return None; - } else if args[0] == "--update" { - hbb_common::allow_err!(platform::update_me()); - return None; } else if args[0] == "--reinstall" { hbb_common::allow_err!(platform::uninstall_me(false)); hbb_common::allow_err!(platform::install_me( diff --git a/src/lib.rs b/src/lib.rs index 31ad83bca..812162e50 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,8 +40,6 @@ use common::*; pub mod cli; #[cfg(not(any(target_os = "android", target_os = "ios", feature = "cli")))] pub mod core_main; -#[cfg(all(windows, feature = "hbbs"))] -mod hbbs; mod lang; #[cfg(windows)] mod license; diff --git a/src/platform/windows.rs b/src/platform/windows.rs index 8d2555fa7..24be72bc2 100644 --- a/src/platform/windows.rs +++ b/src/platform/windows.rs @@ -722,7 +722,7 @@ pub fn is_share_rdp() -> bool { } pub fn set_share_rdp(enable: bool) { - let (subkey, _, _, _, _) = get_install_info(); + let (subkey, _, _, _) = get_install_info(); let cmd = format!( "reg add {} /f /v share_rdp /t REG_SZ /d \"{}\"", subkey, @@ -815,11 +815,11 @@ fn get_valid_subkey() -> String { return get_subkey(&app_name, false); } -pub fn get_install_info() -> (String, String, String, String, String) { +pub fn get_install_info() -> (String, String, String, String) { get_install_info_with_subkey(get_valid_subkey()) } -fn get_default_install_info() -> (String, String, String, String, String) { +fn get_default_install_info() -> (String, String, String, String) { get_install_info_with_subkey(get_subkey(&crate::get_app_name(), false)) } @@ -841,7 +841,6 @@ fn get_default_install_path() -> String { } pub fn check_update_broker_process() -> ResultType<()> { - // let (_, path, _, _) = get_install_info(); let process_exe = privacy_win_mag::INJECTED_PROCESS_EXE; let origin_process_exe = privacy_win_mag::ORIGIN_PROCESS_EXE; @@ -876,19 +875,17 @@ pub fn check_update_broker_process() -> ResultType<()> { let cmds = format!( " chcp 65001 - taskkill /F /IM {broker_exe} + taskkill /F /IM {process_exe} copy /Y \"{origin_process_exe}\" \"{cur_exe}\" ", - broker_exe = process_exe, - origin_process_exe = origin_process_exe, - cur_exe = cur_exe.to_string_lossy().to_string(), + cur_exe = cur_exe.to_string_lossy(), ); run_cmds(cmds, false, "update_broker")?; Ok(()) } -fn get_install_info_with_subkey(subkey: String) -> (String, String, String, String, String) { +fn get_install_info_with_subkey(subkey: String) -> (String, String, String, String) { let mut path = get_reg_of(&subkey, "InstallLocation"); if path.is_empty() { path = get_default_install_path(); @@ -899,8 +896,7 @@ fn get_install_info_with_subkey(subkey: String) -> (String, String, String, Stri crate::get_app_name() ); let exe = format!("{}\\{}.exe", path, crate::get_app_name()); - let dll = format!("{}\\sciter.dll", path); - (subkey, path, start_menu, exe, dll) + (subkey, path, start_menu, exe) } pub fn copy_raw_cmd(src_raw: &str, _raw: &str, _path: &str) -> String { @@ -923,15 +919,14 @@ pub fn copy_exe_cmd(src_exe: &str, exe: &str, path: &str) -> String { {main_exe} copy /Y \"{ORIGIN_PROCESS_EXE}\" \"{path}\\{broker_exe}\" ", - main_exe = main_exe, - path = path, ORIGIN_PROCESS_EXE = privacy_win_mag::ORIGIN_PROCESS_EXE, broker_exe = privacy_win_mag::INJECTED_PROCESS_EXE, ) } +/* // update_me has bad compatibility, so disable it. pub fn update_me() -> ResultType<()> { - let (_, path, _, exe, _dll) = get_install_info(); + let (_, path, _, exe) = get_install_info(); let src_exe = std::env::current_exe()?.to_str().unwrap_or("").to_owned(); let cmds = format!( " @@ -949,16 +944,14 @@ pub fn update_me() -> ResultType<()> { lic = register_licence(), cur_pid = get_current_pid(), ); - std::thread::sleep(std::time::Duration::from_millis(1000)); run_cmds(cmds, false, "update")?; - std::thread::sleep(std::time::Duration::from_millis(2000)); - std::process::Command::new(&exe).arg("--tray").spawn().ok(); - std::process::Command::new(&exe).spawn().ok(); + run_after_run_cmds(false)?; std::process::Command::new(&exe) .args(&["--remove", &src_exe]) .spawn()?; Ok(()) } +*/ fn get_after_install(exe: &str) -> String { let app_name = crate::get_app_name(); @@ -986,24 +979,21 @@ fn get_after_install(exe: &str) -> String { reg add HKEY_CLASSES_ROOT\\{ext}\\shell\\open /f reg add HKEY_CLASSES_ROOT\\{ext}\\shell\\open\\command /f reg add HKEY_CLASSES_ROOT\\{ext}\\shell\\open\\command /f /ve /t REG_SZ /d \"\\\"{exe}\\\" \\\"%%1\\\"\" - sc create {app_name} binpath= \"\\\"{exe}\\\" --service\" start= auto DisplayName= \"{app_name} Service\" netsh advfirewall firewall add rule name=\"{app_name} Service\" dir=in action=allow program=\"{exe}\" enable=yes - sc start {app_name} + {create_service} reg add HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System /f /v SoftwareSASGeneration /t REG_DWORD /d 1 - ", ext=ext, exe=exe, app_name=app_name) + ", create_service=get_create_service(&exe)) } pub fn install_me(options: &str, path: String, silent: bool, debug: bool) -> ResultType<()> { let uninstall_str = get_uninstall(false); let mut path = path.trim_end_matches('\\').to_owned(); - let (subkey, _path, start_menu, exe, dll) = get_default_install_info(); + let (subkey, _path, start_menu, exe) = get_default_install_info(); let mut exe = exe; - let mut _dll = dll; if path.is_empty() { path = _path; } else { exe = exe.replace(&_path, &path); - _dll = _dll.replace(&_path, &path); } let mut version_major = "0"; let mut version_minor = "0"; @@ -1018,6 +1008,7 @@ pub fn install_me(options: &str, path: String, silent: bool, debug: bool) -> Res if versions.len() > 2 { version_build = versions[2]; } + let app_name = crate::get_app_name(); let tmp_path = std::env::temp_dir().to_string_lossy().to_string(); let mk_shortcut = write_cmds( @@ -1029,10 +1020,7 @@ sLinkFile = \"{tmp_path}\\{app_name}.lnk\" Set oLink = oWS.CreateShortcut(sLinkFile) oLink.TargetPath = \"{exe}\" oLink.Save - ", - tmp_path = tmp_path, - app_name = crate::get_app_name(), - exe = exe, + " ), "vbs", "mk_shortcut", @@ -1051,10 +1039,7 @@ Set oLink = oWS.CreateShortcut(sLinkFile) oLink.Arguments = \"--uninstall\" oLink.IconLocation = \"msiexec.exe\" oLink.Save - ", - tmp_path = tmp_path, - app_name = crate::get_app_name(), - exe = exe, + " ), "vbs", "uninstall_shortcut", @@ -1062,27 +1047,7 @@ oLink.Save .to_str() .unwrap_or("") .to_owned(); - let tray_shortcut = 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\" -oLink.Save - ", - tmp_path = tmp_path, - app_name = crate::get_app_name(), - exe = exe, - ), - "vbs", - "tray_shortcut", - )? - .to_str() - .unwrap_or("") - .to_owned(); + let tray_shortcut = get_tray_shortcut(&exe, &tmp_path)?; let mut shortcuts = Default::default(); if options.contains("desktopicon") { shortcuts = format!( @@ -1093,15 +1058,11 @@ oLink.Save } if options.contains("startmenu") { shortcuts = format!( - "{} + "{shortcuts} md \"{start_menu}\" copy /Y \"{tmp_path}\\{app_name}.lnk\" \"{start_menu}\\\" copy /Y \"{tmp_path}\\Uninstall {app_name}.lnk\" \"{start_menu}\\\" - ", - shortcuts, - start_menu = start_menu, - tmp_path = tmp_path, - app_name = crate::get_app_name(), + " ); } @@ -1119,12 +1080,7 @@ 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\" - ", - mk_shortcut = mk_shortcut, - uninstall_shortcut = uninstall_shortcut, - tray_shortcut = tray_shortcut, - tmp_path = tmp_path, - app_name = crate::get_app_name(), + " ); let src_exe = std::env::current_exe()?.to_str().unwrap_or("").to_string(); @@ -1145,11 +1101,12 @@ reg add {subkey} /f /v DisplayIcon /t REG_SZ /d \"{exe}\" reg add {subkey} /f /v DisplayName /t REG_SZ /d \"{app_name}\" reg add {subkey} /f /v DisplayVersion /t REG_SZ /d \"{version}\" reg add {subkey} /f /v Version /t REG_SZ /d \"{version}\" +reg add {subkey} /f /v BuildDate /t REG_SZ /d \"{build_date}\" reg add {subkey} /f /v InstallLocation /t REG_SZ /d \"{path}\" reg add {subkey} /f /v Publisher /t REG_SZ /d \"{app_name}\" -reg add {subkey} /f /v VersionMajor /t REG_DWORD /d {major} -reg add {subkey} /f /v VersionMinor /t REG_DWORD /d {minor} -reg add {subkey} /f /v VersionBuild /t REG_DWORD /d {build} +reg add {subkey} /f /v VersionMajor /t REG_DWORD /d {version_major} +reg add {subkey} /f /v VersionMinor /t REG_DWORD /d {version_minor} +reg add {subkey} /f /v VersionBuild /t REG_DWORD /d {version_build} reg add {subkey} /f /v UninstallString /t REG_SZ /d \"\\\"{exe}\\\" --uninstall\" reg add {subkey} /f /v EstimatedSize /t REG_DWORD /d {size} reg add {subkey} /f /v WindowsInstaller /t REG_DWORD /d 0 @@ -1161,32 +1118,14 @@ copy /Y \"{tmp_path}\\{app_name} Tray.lnk\" \"%PROGRAMDATA%\\Microsoft\\Windows\ {shortcuts} copy /Y \"{tmp_path}\\Uninstall {app_name}.lnk\" \"{path}\\\" {dels} -sc create {app_name} binpath= \"\\\"{exe}\\\" --import-config \\\"{config_path}\\\"\" start= auto DisplayName= \"{app_name} Service\" -sc start {app_name} -sc stop {app_name} -sc delete {app_name} +{import_config} {install_cert} {after_install} {sleep} ", - uninstall_str=uninstall_str, - path=path, - exe=exe, - subkey=subkey, - app_name=crate::get_app_name(), version=crate::VERSION, - major=version_major, - minor=version_minor, - build=version_build, - size=size, - mk_shortcut=mk_shortcut, - uninstall_shortcut=uninstall_shortcut, - tray_shortcut=tray_shortcut, - tmp_path=tmp_path, - shortcuts=shortcuts, - config_path=Config::file().to_str().unwrap_or(""), + build_date=crate::BUILD_DATE, lic=register_licence(), - install_cert=install_cert, after_install=get_after_install(&exe), sleep=if debug { "timeout 300" @@ -1199,19 +1138,15 @@ sc delete {app_name} &dels }, copy_exe = copy_exe_cmd(&src_exe, &exe, &path), + import_config = get_import_config(&exe), ); run_cmds(cmds, debug, "install")?; - std::thread::sleep(std::time::Duration::from_millis(2000)); - if !silent { - std::process::Command::new(&exe).spawn()?; - std::process::Command::new(&exe).arg("--tray").spawn()?; - std::thread::sleep(std::time::Duration::from_millis(1000)); - } + run_after_run_cmds(silent)?; Ok(()) } pub fn run_after_install() -> ResultType<()> { - let (_, _, _, exe, _) = get_install_info(); + let (_, _, _, exe) = get_install_info(); run_cmds(get_after_install(&exe), true, "after_install") } @@ -1235,12 +1170,10 @@ fn get_before_uninstall(kill_self: bool) -> String { taskkill /F /IM {broker_exe} taskkill /F /IM {app_name}.exe{filter} reg delete HKEY_CLASSES_ROOT\\.{ext} /f + reg delete HKEY_CLASSES_ROOT\\{ext} /f netsh advfirewall firewall delete rule name=\"{app_name} Service\" ", - app_name = app_name, broker_exe = WIN_MAG_INJECTED_PROCESS_EXE, - ext = ext, - filter = filter, ) } @@ -1251,8 +1184,7 @@ fn get_uninstall(kill_self: bool) -> String { uninstall_cert_cmd = format!("\"{}\" --uninstall-cert", exe_path); } } - - let (subkey, path, start_menu, _, _) = get_install_info(); + let (subkey, path, start_menu, _) = get_install_info(); format!( " {before_uninstall} @@ -1264,11 +1196,7 @@ fn get_uninstall(kill_self: bool) -> String { if exist \"%PROGRAMDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\{app_name} Tray.lnk\" del /f /q \"%PROGRAMDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\{app_name} Tray.lnk\" ", before_uninstall=get_before_uninstall(kill_self), - uninstall_cert_cmd = uninstall_cert_cmd, - subkey=subkey, app_name = crate::get_app_name(), - path = path, - start_menu = start_menu, ) } @@ -1277,6 +1205,7 @@ pub fn uninstall_me(kill_self: bool) -> ResultType<()> { } fn write_cmds(cmds: String, ext: &str, tip: &str) -> ResultType { + let mut cmds = cmds; let mut tmp = std::env::temp_dir(); // When dir contains these characters, the bat file will not execute in elevated mode. if vec!["&", "@", "^"] @@ -1289,9 +1218,20 @@ fn write_cmds(cmds: String, ext: &str, tip: &str) -> ResultType = cmds.encode_utf16().collect(); // utf8 -> utf16le which vbs support it only @@ -1310,8 +1250,18 @@ fn to_le(v: &mut [u16]) -> &[u8] { unsafe { v.align_to().1 } } +fn get_undone_file(tmp: &PathBuf) -> PathBuf { + let mut tmp1 = tmp.clone(); + tmp1.set_file_name(format!( + "{}.undone", + tmp.file_name().unwrap().to_string_lossy() + )); + tmp1 +} + fn run_cmds(cmds: String, show: bool, tip: &str) -> ResultType<()> { let tmp = write_cmds(cmds, "bat", tip)?; + let tmp2 = get_undone_file(&tmp); let tmp_fn = tmp.to_str().unwrap_or(""); let res = runas::Command::new("cmd") .args(&["/C", &tmp_fn]) @@ -1322,6 +1272,10 @@ fn run_cmds(cmds: String, show: bool, tip: &str) -> ResultType<()> { allow_err!(std::fs::remove_file(tmp)); } let _ = res?; + if tmp2.exists() { + allow_err!(std::fs::remove_file(tmp2)); + bail!("{} failed", tip); + } Ok(()) } @@ -1357,7 +1311,7 @@ pub fn is_installed() -> bool { service::ServiceAccess, service_manager::{ServiceManager, ServiceManagerAccess}, }; - let (_, _, _, exe, _) = get_install_info(); + let (_, _, _, exe) = get_install_info(); if !std::fs::metadata(exe).is_ok() { return false; } @@ -1372,18 +1326,8 @@ pub fn is_installed() -> bool { return false; } -pub fn get_installed_version() -> String { - let (_, _, _, exe, _) = get_install_info(); - if let Ok(output) = std::process::Command::new(exe).arg("--version").output() { - for line in String::from_utf8_lossy(&output.stdout).lines() { - return line.to_owned(); - } - } - "".to_owned() -} - -fn get_reg(name: &str) -> String { - let (subkey, _, _, _, _) = get_install_info(); +pub fn get_reg(name: &str) -> String { + let (subkey, _, _, _) = get_install_info(); get_reg_of(&subkey, name) } @@ -1434,7 +1378,7 @@ pub fn bootstrap() { } fn register_licence() -> String { - let (subkey, _, _, _, _) = get_install_info(); + let (subkey, _, _, _) = get_install_info(); if let Ok(lic) = get_license_from_exe_name() { format!( " @@ -1442,7 +1386,6 @@ fn register_licence() -> String { reg add {subkey} /f /v Host /t REG_SZ /d \"{host}\" reg add {subkey} /f /v Api /t REG_SZ /d \"{api}\" ", - subkey = subkey, key = &lic.key, host = &lic.host, api = &lic.api, @@ -1469,9 +1412,7 @@ Set oLink = oWS.CreateShortcut(sLinkFile) oLink.TargetPath = \"{exe}\" oLink.Arguments = \"--connect {id}\" oLink.Save - ", - exe = exe, - id = id, + " ), "vbs", "connect_shortcut", @@ -2181,6 +2122,117 @@ pub fn is_process_consent_running() -> ResultType { Ok(output.status.success() && !output.stdout.is_empty()) } +pub fn uninstall_service(show_new_window: bool) -> ResultType<()> { + let filter = format!(" /FI \"PID ne {}\"", get_current_pid()); + Config::set_option("stop-service".into(), "Y".into()); + let cmds = format!( + " + chcp 65001 + sc stop {app_name} + sc delete {app_name} + if exist \"%PROGRAMDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\{app_name} Tray.lnk\" del /f /q \"%PROGRAMDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\{app_name} Tray.lnk\" + taskkill /F /IM {app_name}.exe{filter} + ", + app_name = crate::get_app_name(), + ); + if let Err(err) = run_cmds(cmds, false, "uninstall") { + Config::set_option("stop-service".into(), "".into()); + bail!(err); + } + run_after_run_cmds(!show_new_window)?; + std::process::exit(0); +} + +pub fn install_service() -> ResultType<()> { + let (_, _, _, exe) = get_install_info(); + let tmp_path = std::env::temp_dir().to_string_lossy().to_string(); + let tray_shortcut = get_tray_shortcut(&exe, &tmp_path)?; + let filter = format!(" /FI \"PID ne {}\"", get_current_pid()); + Config::set_option("stop-service".into(), "".into()); + let cmds = format!( + " +chcp 65001 +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}\" +taskkill /F /IM {app_name}.exe{filter} + ", + app_name = crate::get_app_name(), + import_config = get_import_config(&exe), + create_service = get_create_service(&exe), + ); + if let Err(err) = run_cmds(cmds, false, "install") { + Config::set_option("stop-service".into(), "Y".into()); + bail!(err); + } + run_after_run_cmds(false)?; + std::process::exit(0); +} + +pub fn get_tray_shortcut(exe: &str, tmp_path: &str) -> ResultType { + 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\" +oLink.Save + ", + app_name = crate::get_app_name(), + ), + "vbs", + "tray_shortcut", + )? + .to_str() + .unwrap_or("") + .to_owned()) +} + +fn get_import_config(exe: &str) -> String { + format!(" +sc create {app_name} binpath= \"\\\"{exe}\\\" --import-config \\\"{config_path}\\\"\" start= auto DisplayName= \"{app_name} Service\" +sc start {app_name} +sc stop {app_name} +sc delete {app_name} +", + app_name = crate::get_app_name(), + config_path=Config::file().to_str().unwrap_or(""), +) +} + +fn get_create_service(exe: &str) -> String { + let stop = Config::get_option("stop-service") == "Y"; + if stop { + format!(" +if exist \"%PROGRAMDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\{app_name} Tray.lnk\" del /f /q \"%PROGRAMDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\{app_name} Tray.lnk\" +", app_name = crate::get_app_name()) + } else { + format!(" +sc create {app_name} binpath= \"\\\"{exe}\\\" --service\" start= auto DisplayName= \"{app_name} Service\" +sc start {app_name} +", + app_name = crate::get_app_name()) + } +} + +fn run_after_run_cmds(silent: bool) -> ResultType<()> { + let (_, _, _, exe) = get_install_info(); + std::thread::sleep(std::time::Duration::from_millis(2000)); + if !silent { + std::process::Command::new(&exe).spawn()?; + } + if Config::get_option("stop-service") != "Y" { + std::process::Command::new(&exe).arg("--tray").spawn()?; + } + std::thread::sleep(std::time::Duration::from_millis(1000)); + Ok(()) +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/tray.rs b/src/tray.rs index 617ec2c93..bf6335154 100644 --- a/src/tray.rs +++ b/src/tray.rs @@ -1,94 +1,3 @@ -#[cfg(target_os = "windows")] -use super::ui_interface::get_option_opt; -#[cfg(target_os = "windows")] -use std::sync::{Arc, Mutex}; -#[cfg(target_os = "windows")] -use trayicon::{MenuBuilder, TrayIconBuilder}; -#[cfg(target_os = "windows")] -use winit::{ - event::Event, - event_loop::{ControlFlow, EventLoop}, -}; - -#[cfg(target_os = "windows")] -#[derive(Clone, Eq, PartialEq, Debug)] -enum Events { - DoubleClickTrayIcon, - StopService, - StartService, -} - -#[cfg(target_os = "windows")] -pub fn start_tray() { - let event_loop = EventLoop::::with_user_event(); - let proxy = event_loop.create_proxy(); - let icon = include_bytes!("../res/tray-icon.ico"); - let mut tray_icon = TrayIconBuilder::new() - .sender_winit(proxy) - .icon_from_buffer(icon) - .tooltip("RustDesk") - .on_double_click(Events::DoubleClickTrayIcon) - .build() - .unwrap(); - let old_state = Arc::new(Mutex::new(0)); - let _sender = crate::ui_interface::SENDER.lock().unwrap(); - event_loop.run(move |event, _, control_flow| { - if get_option_opt("ipc-closed").is_some() { - *control_flow = ControlFlow::Exit; - return; - } else { - *control_flow = ControlFlow::Wait; - } - let stopped = is_service_stopped(); - let state = if stopped { 2 } else { 1 }; - let old = *old_state.lock().unwrap(); - if state != old { - hbb_common::log::info!("State changed"); - let mut m = MenuBuilder::new(); - if state == 2 { - m = m.item( - &crate::client::translate("Start Service".to_owned()), - Events::StartService, - ); - } else { - m = m.item( - &crate::client::translate("Stop service".to_owned()), - Events::StopService, - ); - } - tray_icon.set_menu(&m).ok(); - *old_state.lock().unwrap() = state; - } - - match event { - Event::UserEvent(e) => match e { - Events::DoubleClickTrayIcon => { - crate::run_me(Vec::<&str>::new()).ok(); - } - Events::StopService => { - crate::ipc::set_option("stop-service", "Y"); - } - Events::StartService => { - crate::ipc::set_option("stop-service", ""); - } - }, - _ => (), - } - }); -} - -/// Check if service is stoped. -/// Return [`true`] if service is stoped, [`false`] otherwise. -#[inline] -#[cfg(target_os = "windows")] -fn is_service_stopped() -> bool { - if let Some(v) = get_option_opt("stop-service") { - v == "Y" - } else { - false - } -} - /// Start a tray icon in Linux /// /// [Block] @@ -96,13 +5,13 @@ fn is_service_stopped() -> bool { #[cfg(target_os = "linux")] pub fn start_tray() {} -#[cfg(target_os = "macos")] +#[cfg(any(target_os = "macos", target_os = "windows"))] pub fn start_tray() { use hbb_common::{allow_err, log}; allow_err!(make_tray()); } -#[cfg(target_os = "macos")] +#[cfg(any(target_os = "macos", target_os = "windows"))] pub fn make_tray() -> hbb_common::ResultType<()> { // https://github.com/tauri-apps/tray-icon/blob/dev/examples/tao.rs use hbb_common::anyhow::Context; @@ -111,13 +20,21 @@ pub fn make_tray() -> hbb_common::ResultType<()> { menu::{Menu, MenuEvent, MenuItem}, ClickEvent, TrayEvent, TrayIconBuilder, }; - let mode = dark_light::detect(); - const LIGHT: &[u8] = include_bytes!("../res/mac-tray-light-x2.png"); - const DARK: &[u8] = include_bytes!("../res/mac-tray-dark-x2.png"); - let icon = match mode { - dark_light::Mode::Dark => LIGHT, - _ => DARK, - }; + let icon; + #[cfg(target_os = "macos")] + { + let mode = dark_light::detect(); + const LIGHT: &[u8] = include_bytes!("../res/mac-tray-light-x2.png"); + const DARK: &[u8] = include_bytes!("../res/mac-tray-dark-x2.png"); + icon = match mode { + dark_light::Mode::Dark => LIGHT, + _ => DARK, + }; + } + #[cfg(target_os = "windows")] + { + icon = include_bytes!("../res/tray-icon.ico"); + } let (icon_rgba, icon_width, icon_height) = { let image = image::load_from_memory(icon) .context("Failed to open icon path")? @@ -153,6 +70,7 @@ pub fn make_tray() -> hbb_common::ResultType<()> { event_loop.run(move |_event, _, control_flow| { if !docker_hiden { + #[cfg(target_os = "macos")] crate::platform::macos::hide_dock(); docker_hiden = true; } @@ -160,14 +78,20 @@ pub fn make_tray() -> hbb_common::ResultType<()> { if let Ok(event) = menu_channel.try_recv() { if event.id == quit_i.id() { + #[cfg(target_os = "macos")] crate::platform::macos::uninstall(false); + #[cfg(any(target_os = "linux", target_os = "windows"))] + crate::platform::uninstall_service(false).ok(); } println!("{event:?}"); } if let Ok(event) = tray_channel.try_recv() { if event.event == ClickEvent::Double { + #[cfg(target_os = "macos")] crate::platform::macos::handle_application_should_open_untitled_file(); + #[cfg(target_os = "windows")] + crate::run_me(Vec::<&str>::new()).ok(); } } }); diff --git a/src/ui_interface.rs b/src/ui_interface.rs index 8759f65e6..7ea37bb5e 100644 --- a/src/ui_interface.rs +++ b/src/ui_interface.rs @@ -74,28 +74,7 @@ pub fn install_me(_options: String, _path: String, _silent: bool, _debug: bool) #[inline] pub fn update_me(_path: String) { - #[cfg(target_os = "linux")] - { - allow_err!(crate::platform::linux::exec_privileged(&[ - "apt", "install", "-f", &_path - ])); - allow_err!(std::fs::remove_file(&_path)); - allow_err!(crate::run_me(Vec::<&str>::new())); - } - #[cfg(windows)] - { - let mut path = _path; - if path.is_empty() { - if let Ok(tmp) = std::env::current_exe() { - path = tmp.to_string_lossy().to_string(); - } - } - std::process::Command::new(path) - .arg("--update") - .spawn() - .ok(); - std::process::exit(0); - } + goto_install(); } #[inline] @@ -296,11 +275,24 @@ pub fn set_options(m: HashMap) { #[inline] pub fn set_option(key: String, value: String) { let mut options = OPTIONS.lock().unwrap(); - #[cfg(target_os = "macos")] if &key == "stop-service" { - let is_stop = value == "Y"; - if is_stop && crate::platform::macos::uninstall(true) { - return; + #[cfg(target_os = "macos")] + { + let is_stop = value == "Y"; + if is_stop && crate::platform::macos::uninstall(true) { + return; + } + } + #[cfg(any(target_os = "windows"))] + { + if crate::platform::is_installed() { + if value == "Y" { + crate::platform::install_service().ok(); + } else { + crate::platform::uninstall_service(true).ok(); + } + return; + } } } if value.is_empty() { @@ -396,10 +388,8 @@ pub fn is_installed_lower_version() -> bool { return false; #[cfg(windows)] { - let installed_version = crate::platform::windows::get_installed_version(); - let a = hbb_common::get_version_number(crate::VERSION); - let b = hbb_common::get_version_number(&installed_version); - return a > b; + let b = crate::platform::windows::get_reg("BuildDate"); + return crate::BUILD_DATE.cmp(&b).is_gt(); } }