From f4871a992fec480a501fb0c826938521192ce16d Mon Sep 17 00:00:00 2001 From: rustdesk Date: Thu, 15 Sep 2022 17:41:10 +0800 Subject: [PATCH] refactor core_main, also fix windows flutter restart repeated fatal error crash --- flutter/lib/desktop/pages/server_page.dart | 2 + flutter/lib/models/server_model.dart | 2 - flutter/pubspec.lock | 28 +-- src/common.rs | 1 - src/core_main.rs | 193 ++++++++++++++++++--- src/flutter_ffi.rs | 19 +- src/lib.rs | 13 +- src/main.rs | 179 +------------------ 8 files changed, 197 insertions(+), 240 deletions(-) diff --git a/flutter/lib/desktop/pages/server_page.dart b/flutter/lib/desktop/pages/server_page.dart index 62e60ba26..9ca446dcb 100644 --- a/flutter/lib/desktop/pages/server_page.dart +++ b/flutter/lib/desktop/pages/server_page.dart @@ -1,3 +1,5 @@ +// original cm window in Sciter version. + import 'dart:async'; import 'package:flutter/material.dart'; diff --git a/flutter/lib/models/server_model.dart b/flutter/lib/models/server_model.dart index 737d0b22b..a26fe5062 100644 --- a/flutter/lib/models/server_model.dart +++ b/flutter/lib/models/server_model.dart @@ -259,7 +259,6 @@ class ServerModel with ChangeNotifier { Future startService() async { _isStart = true; notifyListeners(); - // TODO parent.target?.ffiModel.updateEventListener(""); await parent.target?.invokeMethod("init_service"); await bind.mainStartService(); @@ -274,7 +273,6 @@ class ServerModel with ChangeNotifier { /// Stop the screen sharing service. Future stopService() async { _isStart = false; - // TODO closeAll(); await parent.target?.invokeMethod("stop_service"); await bind.mainStopService(); diff --git a/flutter/pubspec.lock b/flutter/pubspec.lock index 251d3dacb..dbdf1637b 100644 --- a/flutter/pubspec.lock +++ b/flutter/pubspec.lock @@ -49,7 +49,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.8.2" + version: "2.9.0" back_button_interceptor: dependency: "direct main" description: @@ -147,7 +147,7 @@ packages: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.2.1" charcode: dependency: transitive description: @@ -168,7 +168,7 @@ packages: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" code_builder: dependency: transitive description: @@ -324,7 +324,7 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.3.1" ffi: dependency: "direct main" description: @@ -418,8 +418,8 @@ packages: dependency: "direct main" description: path: "." - ref: "9021e21de36c84edf01d5034f38eda580463163b" - resolved-ref: "9021e21de36c84edf01d5034f38eda580463163b" + ref: "47179378523c993092f70d95f93d53f40af01f02" + resolved-ref: "47179378523c993092f70d95f93d53f40af01f02" url: "https://github.com/Kingtous/rustdesk_flutter_custom_cursor" source: git version: "0.0.1" @@ -630,14 +630,14 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.11" + version: "0.12.12" material_color_utilities: dependency: transitive description: name: material_color_utilities url: "https://pub.dartlang.org" source: hosted - version: "0.1.4" + version: "0.1.5" menu_base: dependency: transitive description: @@ -651,7 +651,7 @@ packages: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.0" mime: dependency: transitive description: @@ -728,7 +728,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.1" + version: "1.8.2" path_provider: dependency: "direct main" description: @@ -980,7 +980,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.2" + version: "1.9.0" sqflite: dependency: transitive description: @@ -1022,7 +1022,7 @@ packages: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" synchronized: dependency: transitive description: @@ -1036,14 +1036,14 @@ packages: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.2.1" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.9" + version: "0.4.12" timing: dependency: transitive description: diff --git a/src/common.rs b/src/common.rs index d5ccf0e1b..37057b809 100644 --- a/src/common.rs +++ b/src/common.rs @@ -2,7 +2,6 @@ use std::sync::{Arc, Mutex}; #[cfg(not(any(target_os = "android", target_os = "ios")))] pub use arboard::Clipboard as ClipboardContext; -use serde_json::json; use hbb_common::{ allow_err, diff --git a/src/core_main.rs b/src/core_main.rs index cecbf4115..3c1d858fb 100644 --- a/src/core_main.rs +++ b/src/core_main.rs @@ -1,39 +1,188 @@ use hbb_common::log; -use crate::{flutter::connection_manager, start_os_service, start_server}; - -/// Main entry of the RustDesk Core. -/// Return true if the app should continue running with UI(possibly Flutter), false if the app should exit. -pub fn core_main() -> bool { - let args = std::env::args().collect::>(); - // TODO: implement core_main() - if args.len() > 1 { - if args[1] == "--cm" { - // call connection manager to establish connections - // meanwhile, return true to call flutter window to show control panel - connection_manager::start_listen_ipc_thread(); - return true; +// shared by flutter and sciter main function +pub fn core_main() -> Option> { + // https://docs.rs/flexi_logger/latest/flexi_logger/error_info/index.html#write + // though async logger more efficient, but it also causes more problems, disable it for now + // let mut _async_logger_holder: Option = None; + let mut args = Vec::new(); + let mut i = 0; + let mut is_setup = false; + for arg in std::env::args() { + // to-do: how to pass to flutter? + if i == 0 && crate::common::is_setup(&arg) { + is_setup = true; + } else if i > 0 { + args.push(arg); } - + i += 1; + } + if is_setup { + if args.is_empty() { + args.push("--install".to_owned()); + } else if args[0] == "--noinstall" { + args.clear(); + } + } + if args.len() > 0 && args[0] == "--version" { + println!("{}", crate::VERSION); + return None; + } + #[cfg(debug_assertions)] + { use hbb_common::env_logger::*; init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "info")); - if args[1] == "--service" { - log::info!("start --service"); - start_os_service(); - return false; + } + #[cfg(not(debug_assertions))] + { + let mut path = hbb_common::config::Config::log_path(); + if args.len() > 0 && args[0].starts_with("--") { + let name = args[0].replace("--", ""); + if !name.is_empty() { + path.push(name); + } } - if args[1] == "--server" { + use flexi_logger::*; + if let Ok(x) = Logger::try_with_env_or_str("debug") { + // _async_logger_holder = + x.log_to_file(FileSpec::default().directory(path)) + //.write_mode(WriteMode::Async) + .format(opt_format) + .rotate( + Criterion::Age(Age::Day), + Naming::Timestamps, + Cleanup::KeepLogFiles(6), + ) + .start() + .ok(); + } + } + if args.is_empty() { + std::thread::spawn(move || crate::start_server(false)); + } else { + #[cfg(windows)] + { + use crate::platform; + if args[0] == "--uninstall" { + if let Err(err) = platform::uninstall_me() { + log::error!("Failed to uninstall: {}", err); + } + return None; + } else if args[0] == "--after-install" { + if let Err(err) = platform::run_after_install() { + log::error!("Failed to after-install: {}", err); + } + return None; + } else if args[0] == "--before-uninstall" { + if let Err(err) = platform::run_before_uninstall() { + 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()); + hbb_common::allow_err!(platform::install_me( + "desktopicon startmenu", + "".to_owned(), + false, + false, + )); + return None; + } else if args[0] == "--silent-install" { + hbb_common::allow_err!(platform::install_me( + "desktopicon startmenu", + "".to_owned(), + true, + args.len() > 1, + )); + return None; + } else if args[0] == "--extract" { + #[cfg(feature = "with_rc")] + hbb_common::allow_err!(crate::rc::extract_resources(&args[1])); + return None; + } + } + if args[0] == "--remove" { + if args.len() == 2 { + // sleep a while so that process of removed exe exit + std::thread::sleep(std::time::Duration::from_secs(1)); + std::fs::remove_file(&args[1]).ok(); + return None; + } + } else if args[0] == "--service" { + log::info!("start --service"); + crate::start_os_service(); + return None; + } else if args[0] == "--server" { log::info!("start --server"); #[cfg(not(target_os = "macos"))] { - start_server(true); + crate::start_server(true); + return None; } #[cfg(target_os = "macos")] { std::thread::spawn(move || start_server(true)); + // to-do: for flutter, starting tray not ready yet, or we can reuse sciter's tray implementation. } - return false; + } else if args[0] == "--import-config" { + if args.len() == 2 { + let filepath; + let path = std::path::Path::new(&args[1]); + if !path.is_absolute() { + let mut cur = std::env::current_dir().unwrap(); + cur.push(path); + filepath = cur.to_str().unwrap().to_string(); + } else { + filepath = path.to_str().unwrap().to_string(); + } + import_config(&filepath); + } + return None; + } else if args[0] == "--password" { + if args.len() == 2 { + crate::ipc::set_permanent_password(args[1].to_owned()).unwrap(); + } + return None; + } else if args[0] == "--check-hwcodec-config" { + #[cfg(feature = "hwcodec")] + scrap::hwcodec::check_config(); + return None; + } else if args[0] == "--cm" { + // call connection manager to establish connections + // meanwhile, return true to call flutter window to show control panel + #[cfg(feature = "flutter")] + crate::flutter::connection_manager::start_listen_ipc_thread(); + } + } + //_async_logger_holder.map(|x| x.flush()); + Some(args) +} + +fn import_config(path: &str) { + use hbb_common::{config::*, get_exe_time, get_modified_time}; + let path2 = path.replace(".toml", "2.toml"); + let path2 = std::path::Path::new(&path2); + let path = std::path::Path::new(path); + log::info!("import config from {:?} and {:?}", path, path2); + let config: Config = load_path(path.into()); + if config.is_empty() { + log::info!("Empty source config, skipped"); + return; + } + if get_modified_time(&path) > get_modified_time(&Config::file()) + && get_modified_time(&path) < get_exe_time() + { + if store_path(Config::file(), config).is_err() { + log::info!("config written"); + } + } + let config2: Config2 = load_path(path2.into()); + if get_modified_time(&path2) > get_modified_time(&Config2::file()) { + if store_path(Config2::file(), config2).is_err() { + log::info!("config2 written"); } } - true } diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index 568096b1c..6f73aa768 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -33,14 +33,6 @@ use crate::{ fn initialize(app_dir: &str) { *config::APP_DIR.write().unwrap() = app_dir.to_owned(); - #[cfg(feature = "cli")] - { - #[cfg(any(target_os = "android", target_os = "ios"))] - { - crate::common::test_rendezvous_server(); - crate::common::test_nat_type(); - } - } #[cfg(target_os = "android")] { android_logger::init_once( @@ -58,13 +50,6 @@ fn initialize(app_dir: &str) { { crate::common::check_software_update(); } - #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] - { - use hbb_common::env_logger::*; - if let Err(e) = try_init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "debug")) { - log::debug!("{}", e); - } - } } /// FFI for rustdesk core's main entry. @@ -72,7 +57,7 @@ fn initialize(app_dir: &str) { #[no_mangle] pub extern "C" fn rustdesk_core_main() -> bool { #[cfg(not(any(target_os = "android", target_os = "ios")))] - return crate::core_main::core_main(); + return crate::core_main::core_main().is_some(); #[cfg(any(target_os = "android", target_os = "ios"))] false } @@ -843,8 +828,6 @@ pub fn main_start_service() { config::Config::set_option("stop-service".into(), "".into()); crate::rendezvous_mediator::RendezvousMediator::restart(); } - #[cfg(not(target_os = "android"))] - std::thread::spawn(move || start_server(true)); } pub fn main_update_temporary_password() { diff --git a/src/lib.rs b/src/lib.rs index b427c3301..a5041e9f8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,10 +10,10 @@ mod server; pub use self::server::*; mod client; #[cfg(not(any(target_os = "ios")))] -mod rendezvous_mediator; -#[cfg(not(any(target_os = "ios")))] mod lan; #[cfg(not(any(target_os = "ios")))] +mod rendezvous_mediator; +#[cfg(not(any(target_os = "ios")))] pub use self::rendezvous_mediator::*; /// cbindgen:ignore pub mod common; @@ -30,13 +30,10 @@ pub mod flutter; #[cfg(any(target_os = "android", target_os = "ios", feature = "flutter"))] pub mod flutter_ffi; use common::*; -#[cfg(all( - not(any(target_os = "android", target_os = "ios")), - feature = "flutter" -))] -pub mod core_main; #[cfg(feature = "cli")] 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; @@ -47,9 +44,9 @@ mod port_forward; #[cfg(windows)] mod tray; +mod ui_cm_interface; mod ui_interface; mod ui_session_interface; -mod ui_cm_interface; #[cfg(windows)] pub mod clipboard_file; diff --git a/src/main.rs b/src/main.rs index 0acdde68f..23559ed8a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,6 @@ // Requires Rust 1.18. //#![windows_subsystem = "windows"] -use hbb_common::log; use librustdesk::*; #[cfg(any(target_os = "android", target_os = "ios"))] @@ -15,184 +14,14 @@ fn main() { #[cfg(not(any(target_os = "android", target_os = "ios", feature = "cli")))] fn main() { - // https://docs.rs/flexi_logger/latest/flexi_logger/error_info/index.html#write - let mut _async_logger_holder: Option = None; - let mut args = Vec::new(); - let mut i = 0; - let mut is_setup = false; - for arg in std::env::args() { - if i == 0 && common::is_setup(&arg) { - is_setup = true; - } else if i > 0 { - args.push(arg); - } - i += 1; - } - if is_setup { - if args.is_empty() { - args.push("--install".to_owned()); - } else if args[0] == "--noinstall" { - args.clear(); - } - } - if args.len() > 0 && args[0] == "--version" { - println!("{}", crate::VERSION); - return; - } - #[cfg(not(feature = "inline"))] - { - use hbb_common::env_logger::*; - init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "info")); - } - #[cfg(feature = "inline")] - { - let mut path = hbb_common::config::Config::log_path(); - if args.len() > 0 && args[0].starts_with("--") { - let name = args[0].replace("--", ""); - if !name.is_empty() { - path.push(name); - } - } - use flexi_logger::*; - if let Ok(x) = Logger::try_with_env_or_str("debug") { - _async_logger_holder = x - .log_to_file(FileSpec::default().directory(path)) - .write_mode(WriteMode::Async) - .format(opt_format) - .rotate( - Criterion::Age(Age::Day), - Naming::Timestamps, - Cleanup::KeepLogFiles(6), - ) - .start() - .ok(); - } - } - if args.is_empty() { - std::thread::spawn(move || start_server(false)); - } else { - #[cfg(windows)] - { - if args[0] == "--uninstall" { - if let Err(err) = platform::uninstall_me() { - log::error!("Failed to uninstall: {}", err); - } - return; - } else if args[0] == "--after-install" { - if let Err(err) = platform::run_after_install() { - log::error!("Failed to after-install: {}", err); - } - return; - } else if args[0] == "--before-uninstall" { - if let Err(err) = platform::run_before_uninstall() { - log::error!("Failed to before-uninstall: {}", err); - } - return; - } else if args[0] == "--update" { - hbb_common::allow_err!(platform::update_me()); - return; - } else if args[0] == "--reinstall" { - hbb_common::allow_err!(platform::uninstall_me()); - hbb_common::allow_err!(platform::install_me( - "desktopicon startmenu", - "".to_owned(), - false, - false, - )); - return; - } else if args[0] == "--silent-install" { - hbb_common::allow_err!(platform::install_me( - "desktopicon startmenu", - "".to_owned(), - true, - args.len() > 1, - )); - return; - } else if args[0] == "--extract" { - #[cfg(feature = "with_rc")] - hbb_common::allow_err!(crate::rc::extract_resources(&args[1])); - return; - } - } - if args[0] == "--remove" { - if args.len() == 2 { - // sleep a while so that process of removed exe exit - std::thread::sleep(std::time::Duration::from_secs(1)); - std::fs::remove_file(&args[1]).ok(); - return; - } - } else if args[0] == "--service" { - log::info!("start --service"); - start_os_service(); - return; - } else if args[0] == "--server" { - log::info!("start --server"); - #[cfg(not(target_os = "macos"))] - { - start_server(true); - return; - } - #[cfg(target_os = "macos")] - { - std::thread::spawn(move || start_server(true)); - } - } else if args[0] == "--import-config" { - if args.len() == 2 { - let filepath; - let path = std::path::Path::new(&args[1]); - if !path.is_absolute() { - let mut cur = std::env::current_dir().unwrap(); - cur.push(path); - filepath = cur.to_str().unwrap().to_string(); - } else { - filepath = path.to_str().unwrap().to_string(); - } - import_config(&filepath); - } - return; - } else if args[0] == "--password" { - if args.len() == 2 { - ipc::set_permanent_password(args[1].to_owned()).unwrap(); - } - return; - } else if args[0] == "--check-hwcodec-config" { - #[cfg(feature = "hwcodec")] - scrap::hwcodec::check_config(); - return; - } - } - ui::start(&mut args[..]); - _async_logger_holder.map(|x| x.flush()); -} - -fn import_config(path: &str) { - use hbb_common::{config::*, get_exe_time, get_modified_time}; - let path2 = path.replace(".toml", "2.toml"); - let path2 = std::path::Path::new(&path2); - let path = std::path::Path::new(path); - log::info!("import config from {:?} and {:?}", path, path2); - let config: Config = load_path(path.into()); - if config.is_empty() { - log::info!("Empty source config, skipped"); - return; - } - if get_modified_time(&path) > get_modified_time(&Config::file()) - && get_modified_time(&path) < get_exe_time() - { - if store_path(Config::file(), config).is_err() { - log::info!("config written"); - } - } - let config2: Config2 = load_path(path2.into()); - if get_modified_time(&path2) > get_modified_time(&Config2::file()) { - if store_path(Config2::file(), config2).is_err() { - log::info!("config2 written"); - } + if let Some(args) = crate::core_main::core_main().as_mut() { + ui::start(args); } } #[cfg(feature = "cli")] fn main() { + use hbb_common::log; use clap::App; let args = format!( "-p, --port-forward=[PORT-FORWARD-OPTIONS] 'Format: remote-id:local-port:remote-port[:remote-host]' @@ -235,4 +64,4 @@ fn main() { let token = LocalConfig::get_option("access_token"); cli::start_one_port_forward(options[0].clone(), port, remote_host, remote_port, key, token); } -} +} \ No newline at end of file