diff --git a/flutter/lib/models/native_model.dart b/flutter/lib/models/native_model.dart index ef885fff8..3f81ba422 100644 --- a/flutter/lib/models/native_model.dart +++ b/flutter/lib/models/native_model.dart @@ -108,24 +108,21 @@ class PlatformFFI { _ffiBind.sessionRegisterGpuTexture( sessionId: sessionId, display: display, ptr: ptr); - _loadDyLib() async { + /// Init the FFI class, loads the native Rust core library. + Future init(String appType) async { + _appType = appType; + final dylib = isAndroid + ? DynamicLibrary.open('librustdesk.so') + : isLinux + ? DynamicLibrary.open('librustdesk.so') + : isWindows + ? DynamicLibrary.open('librustdesk.dll') + : isMacOS + ? DynamicLibrary.open("liblibrustdesk.dylib") + : DynamicLibrary.process(); + debugPrint('initializing FFI $_appType'); try { - final dylib = isAndroid - ? DynamicLibrary.open('librustdesk.so') - : isLinux - ? DynamicLibrary.open('librustdesk.so') - : isWindows - ? DynamicLibrary.open('librustdesk.dll') - : isMacOS - ? DynamicLibrary.open("liblibrustdesk.dylib") - : DynamicLibrary.process(); - try { - _session_get_rgba = - dylib.lookupFunction("session_get_rgba"); - } catch (e) { - print('Failed to lookup function "session_get_rgba": $e'); - exit(1); - } + _session_get_rgba = dylib.lookupFunction("session_get_rgba"); try { // SYSTEM user failed _dir = (await getApplicationDocumentsDirectory()).path; @@ -133,19 +130,7 @@ class PlatformFFI { debugPrint('Failed to get documents directory: $e'); } _ffiBind = RustdeskImpl(dylib); - } catch (e) { - print('Failed to load dynamic library: $e'); - exit(1); - } - } - /// Init the FFI class, loads the native Rust core library. - Future init(String appType) async { - _appType = appType; - await _loadDyLib(); - - debugPrint('initializing FFI $_appType'); - try { if (isLinux) { // Start a dbus service, no need to await _ffiBind.mainStartDbusServer(); diff --git a/flutter/linux/main.cc b/flutter/linux/main.cc index f887e133d..8c2984d72 100644 --- a/flutter/linux/main.cc +++ b/flutter/linux/main.cc @@ -6,21 +6,31 @@ typedef bool (*RustDeskCoreMain)(); bool gIsConnectionManager = false; +void print_help_install_pkg(const char* so); + bool flutter_rustdesk_core_main() { void* librustdesk = dlopen(RUSTDESK_LIB_PATH, RTLD_LAZY); if (!librustdesk) { - fprintf(stderr,"load librustdesk.so failed\n"); + fprintf(stderr,"Failed to load \"librustdesk.so\"\n"); char* error; if ((error = dlerror()) != nullptr) { - fprintf(stderr, "%s", error); + fprintf(stderr, "%s\n", error); + // libnsl.so.1: cannot open shared object file: No such file or directory + char* libmissed = strstr(error, ": cannot open shared object file: No such file or directory"); + if (libmissed != nullptr) { + *libmissed = '\0'; + char* so = strdup(error); + print_help_install_pkg(so); + free(so); + } } - return true; + return false; } auto core_main = (RustDeskCoreMain) dlsym(librustdesk,"rustdesk_core_main"); char* error; if ((error = dlerror()) != nullptr) { - fprintf(stderr, "error finding rustdesk_core_main: %s", error); - return true; + fprintf(stderr, "Program entry \"rustdesk_core_main\" is not found: %s\n", error); + return false; } return core_main(); } @@ -37,3 +47,80 @@ int main(int argc, char** argv) { g_autoptr(MyApplication) app = my_application_new(); return g_application_run(G_APPLICATION(app), argc, argv); } + +typedef struct { + const char* mgr; + const char* search; +} PkgMgrSearch; + +const PkgMgrSearch g_mgrs[] = { + { + "apt", + "apt-file search", + }, + { + "dnf", + "dnf provides", + }, + { + "yum", + "yum provides", + }, + { + "zypper", + "zypper wp", + }, + { + "pacman", + "pacman -Qo", + }, + { + NULL, + NULL, + }, +}; + +int is_command_exists(const char* command) { + char* path = getenv("PATH"); + char* path_copy = strdup(path); + char* dir = strtok(path_copy, ":"); + + while (dir != NULL) { + char command_path[256]; + snprintf(command_path, sizeof(command_path), "%s/%s", dir, command); + if (access(command_path, X_OK) == 0) { + free(path_copy); + return 1; + } + dir = strtok(NULL, ":"); + } + + free(path_copy); + return 0; +} + +// We do not automatically search pkg +// as the search process can be time consuming and update may be required. +void print_help_install_pkg(const char* so) +{ + if (strcmp(so, "libnsl.so.1") == 0) { + const char* mgr[] = {"yum", "dnf", NULL}; + const char** m = mgr; + while (*m != NULL) { + if (is_command_exists(*m)) { + fprintf(stderr, "Please run \"%s install libnsl\" to install the required package.\n", *m); + return; + } + m++; + } + } + + const PkgMgrSearch *mgr_search = g_mgrs; + while (mgr_search->mgr != NULL) { + if (is_command_exists(mgr_search->mgr) == 1) { + fprintf(stderr, "Please run \"%s %s\" to search and install the pkg.\n", mgr_search->search, so); + break; + } + mgr_search++; + } +}