diff --git a/.github/workflows/flutter-nightly.yml b/.github/workflows/flutter-nightly.yml index f2391e77e..074eafe08 100644 --- a/.github/workflows/flutter-nightly.yml +++ b/.github/workflows/flutter-nightly.yml @@ -15,7 +15,7 @@ env: jobs: build-for-windows: - name: ${{ matrix.job.target }} (${{ matrix.job.os }}) + name: ${{ matrix.job.target }} (${{ matrix.job.os }}) ${{ matrix.job.suffix }} runs-on: ${{ matrix.job.os }} strategy: fail-fast: false @@ -23,7 +23,8 @@ jobs: job: # - { target: i686-pc-windows-msvc , os: windows-2019 } # - { target: x86_64-pc-windows-gnu , os: windows-2019 } - - { target: x86_64-pc-windows-msvc , os: windows-2019 } + - { target: x86_64-pc-windows-msvc , os: windows-2019, suffix: "" , extra-build-args: "" } + - { target: x86_64-pc-windows-msvc , os: windows-2019, suffix: "-qs", extra-build-args: "--quick_start" } steps: - name: Checkout source code uses: actions/checkout@v3 @@ -83,13 +84,13 @@ jobs: shell: bash - name: Build rustdesk - run: python3 .\build.py --portable --hwcodec --flutter + run: python3 .\build.py --portable --hwcodec --flutter ${{ matrix.job.extra-build-args }} - name: Rename rustdesk shell: bash run: | for name in rustdesk*??-install.exe; do - mv "$name" "${name%%-install.exe}-${{ matrix.job.target }}.exe" + mv "$name" "${name%%-install.exe}-${{ matrix.job.target }}${{ matrix.job.suffix }}.exe" done - name: Publish Release diff --git a/Cargo.toml b/Cargo.toml index 836bd07d4..44df74952 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ flutter = ["flutter_rust_bridge"] default = ["use_dasp"] hwcodec = ["scrap/hwcodec"] mediacodec = ["scrap/mediacodec"] +quick_start = [] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/build.py b/build.py index c907334ce..a887ff070 100755 --- a/build.py +++ b/build.py @@ -81,6 +81,11 @@ def make_parser(): action='store_true', help='Build windows portable' ) + parser.add_argument( + '--quick_start', + action='store_true', + help='Windows quick start portable' + ) parser.add_argument( '--flatpak', action='store_true', @@ -189,6 +194,8 @@ def get_features(args): features = ['inline'] if windows: features.extend(get_rc_features(args)) + if args.quick_start: + features.append('quick_start') if args.hwcodec: features.append('hwcodec') if args.flutter: diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index fc5b8e574..f73c6b0da 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -90,6 +90,9 @@ class _ConnectionPageState extends State Get.forceAppUpdate(); } isWindowMinisized = false; + } else if (eventName == 'close') { + // called more then one time + bind.mainOnMainWindowClose(); } } diff --git a/src/core_main.rs b/src/core_main.rs index 31b2ae118..f89b613bf 100644 --- a/src/core_main.rs +++ b/src/core_main.rs @@ -81,6 +81,13 @@ pub fn core_main() -> Option> { } } #[cfg(windows)] + #[cfg(feature = "quick_start")] + if !crate::platform::is_installed() && args.is_empty() && !_is_elevate && !_is_run_as_system { + if let Err(e) = crate::portable_service::client::start_portable_service() { + log::error!("Failed to start portable service:{:?}", e); + } + } + #[cfg(windows)] if !crate::platform::is_installed() && (_is_elevate || _is_run_as_system) { crate::platform::elevate_or_run_as_system(click_setup, _is_elevate, _is_run_as_system); return None; @@ -277,7 +284,7 @@ fn core_main_invoke_new_connection(mut args: std::env::Args) -> Option Sync } pub fn main_set_peer_alias(id: String, alias: String) { - main_broadcast_message(&HashMap::from([("name", "alias"), ("id", &id), ("alias", &alias)])); + main_broadcast_message(&HashMap::from([ + ("name", "alias"), + ("id", &id), + ("alias", &alias), + ])); set_peer_option(id, "alias".to_owned(), alias) } @@ -1173,6 +1177,11 @@ pub fn main_account_auth_result() -> String { account_auth_result() } +pub fn main_on_main_window_close() { + #[cfg(windows)] + crate::portable_service::client::drop_portable_service_shared_memory(); +} + #[cfg(target_os = "android")] pub mod server_side { use jni::{ diff --git a/src/platform/windows.rs b/src/platform/windows.rs index 34f132894..19c092f29 100644 --- a/src/platform/windows.rs +++ b/src/platform/windows.rs @@ -1553,6 +1553,13 @@ pub fn run_as_system(arg: &str) -> ResultType<()> { pub fn elevate_or_run_as_system(is_setup: bool, is_elevate: bool, is_run_as_system: bool) { // avoid possible run recursively due to failed run. + log::info!( + "elevate:{}->{:?}, run_as_system:{}->{}", + is_elevate, + is_elevated(None), + is_run_as_system, + crate::username(), + ); let arg_elevate = if is_setup { "--noinstall --elevate" } else { diff --git a/src/server/portable_service.rs b/src/server/portable_service.rs index 21b501f1e..861b04b3d 100644 --- a/src/server/portable_service.rs +++ b/src/server/portable_service.rs @@ -406,8 +406,9 @@ pub mod server { Pong => { nack = 0; } - ConnCount(Some(n)) => { - if n == 0 { + ConnCount(Some(_n)) => { + #[cfg(not(feature = "quick_start"))] + if _n == 0 { log::info!("Connnection count equals 0, exit"); stream.send(&Data::DataPortableService(WillClose)).await.ok(); break; @@ -435,6 +436,7 @@ pub mod server { break; } stream.send(&Data::DataPortableService(Ping)).await.ok(); + #[cfg(not(feature = "quick_start"))] stream.send(&Data::DataPortableService(ConnCount(None))).await.ok(); } } @@ -462,6 +464,7 @@ pub mod client { } pub(crate) fn start_portable_service() -> ResultType<()> { + log::info!("start portable service"); if PORTABLE_SERVICE_RUNNING.lock().unwrap().clone() { bail!("already running"); } @@ -484,7 +487,7 @@ pub mod client { crate::portable_service::SHMEM_NAME, shmem_size, )?); - shutdown_hooks::add_shutdown_hook(drop_shmem); + shutdown_hooks::add_shutdown_hook(drop_portable_service_shared_memory); } let mut option = SHMEM.lock().unwrap(); let shmem = option.as_mut().unwrap(); @@ -504,7 +507,7 @@ pub mod client { Ok(()) } - extern "C" fn drop_shmem() { + pub extern "C" fn drop_portable_service_shared_memory() { log::info!("drop shared memory"); *SHMEM.lock().unwrap() = None; }