Fix conflicts

This commit is contained in:
NicKoehler 2023-03-08 16:57:51 +01:00
commit bcfb649815
No known key found for this signature in database
GPG Key ID: BAE01394EB51AC58
52 changed files with 525 additions and 135 deletions

View File

@ -86,7 +86,7 @@ jobs:
shell: bash
- name: Build rustdesk
run: python3 .\build.py --portable --hwcodec --flutter
run: python3 .\build.py --portable --hwcodec --flutter --feature IddDriver
- name: Sign rustdesk files
uses: GermanBluefox/code-sign-action@v7

1
Cargo.lock generated
View File

@ -4943,6 +4943,7 @@ dependencies = [
"flutter_rust_bridge_codegen",
"fruitbasket",
"hbb_common",
"hex",
"hound",
"image 0.24.5",
"impersonate_system",

View File

@ -64,6 +64,7 @@ errno = "0.2.8"
rdev = { git = "https://github.com/fufesou/rdev" }
url = { version = "2.1", features = ["serde"] }
dlopen = "0.1"
hex = "0.4.3"
reqwest = { version = "0.11", features = ["blocking", "json", "rustls-tls"], default-features=false }
chrono = "0.4.23"
@ -87,7 +88,7 @@ system_shutdown = "3.0.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"] }
winapi = { version = "0.3", features = ["winuser", "wincrypt"] }
winreg = "0.10"
windows-service = "0.4"
virtual_display = { path = "libs/virtual_display" }

View File

@ -37,7 +37,7 @@ def parse_rc_features(feature):
'IddDriver': {
'zip_url': 'https://github.com/fufesou/RustDeskIddDriver/releases/download/v0.1/RustDeskIddDriver_x64.zip',
'checksum_url': 'https://github.com/fufesou/RustDeskIddDriver/releases/download/v0.1/checksum_md5',
'exclude': ['README.md'],
'exclude': ['README.md', 'certmgr.exe', 'install_cert_runas_admin.bat'],
},
'PrivacyMode': {
'zip_url': 'https://github.com/fufesou/RustDeskTempTopMostWindow/releases/download/v0.1'

View File

@ -6,18 +6,18 @@
<a href="#dateistruktur">Dateistruktur</a>
<a href="#screenshots">Screenshots</a><br>
[<a href="../README.md">English</a>] | [<a href="README-UA.md">Українська</a>] | [<a href="README-CS.md">česky</a>] | [<a href="README-ZH.md">中文</a>] | [<a href="README-HU.md">Magyar</a>] | [<a href="README-ES.md">Español</a>] | [<a href="README-FA.md">فارسی</a>] | [<a href="README-FR.md">Français</a>] | [<a href="README-PL.md">Polski</a>] | [<a href="README-ID.md">Indonesian</a>] | [<a href="README-FI.md">Suomi</a>] | [<a href="README-ML.md">മലയാളം</a>] | [<a href="README-JP.md">日本語</a>] | [<a href="README-NL.md">Nederlands</a>] | [<a href="README-IT.md">Italiano</a>] | [<a href="README-RU.md">Русский</a>] | [<a href="README-PTBR.md">Português (Brasil)</a>] | [<a href="README-EO.md">Esperanto</a>] | [<a href="README-KR.md">한국어</a>] | [<a href="README-AR.md">العربي</a>] | [<a href="README-VN.md">Tiếng Việt</a>] | [<a href="README-DA.md">Dansk</a>] | [<a href="README-GR.md">Ελληνικά</a>]<br>
<b>Wir brauchen deine Hilfe, um dieses README, die <a href="https://github.com/rustdesk/rustdesk/tree/master/src/lang">RustDesk-Benutzeroberfläche</a> und die <a href="https://github.com/rustdesk/doc.rustdesk.com">Dokumentation</a> in deine Muttersprache zu übersetzen.</b>
<b>Wir brauchen Ihre Hilfe, um dieses README, die <a href="https://github.com/rustdesk/rustdesk/tree/master/src/lang">RustDesk-Benutzeroberfläche</a> und die <a href="https://github.com/rustdesk/doc.rustdesk.com">Dokumentation</a> in Ihre Muttersprache zu übersetzen.</b>
</p>
Rede mit uns auf: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
Reden Sie mit uns auf: [Discord](https://discord.gg/nDceKgxnkV) | [Twitter](https://twitter.com/rustdesk) | [Reddit](https://www.reddit.com/r/rustdesk)
[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/I2I04VU09)
RustDesk ist eine in Rust geschriebene Remote-Desktop-Software, die out of the box ohne besondere Konfiguration funktioniert. Du hast die volle Kontrolle über deine Daten und musst dir keine Sorgen um die Sicherheit machen. Du kannst unseren Rendezvous/Relay-Server nutzen, [einen eigenen Server aufsetzen](https://rustdesk.com/server) oder [einen eigenen Server programmieren](https://github.com/rustdesk/rustdesk-server-demo).
RustDesk ist eine in Rust geschriebene Remote-Desktop-Software, die out of the box ohne besondere Konfiguration funktioniert. Sie haben die volle Kontrolle über Ihre Daten und müssen sich keine Sorgen um die Sicherheit machen. Sie können unseren Rendezvous/Relay-Server nutzen, [einen eigenen Server aufsetzen](https://rustdesk.com/server) oder [einen eigenen Server programmieren](https://github.com/rustdesk/rustdesk-server-demo).
![image](https://user-images.githubusercontent.com/71636191/171661982-430285f0-2e12-4b1d-9957-4a58e375304d.png)
RustDesk heißt jegliche Mitarbeit willkommen. Schau dir [CONTRIBUTING-DE.md](CONTRIBUTING-DE.md) an, wenn du Unterstützung beim Start brauchst.
RustDesk heißt jegliche Mitarbeit willkommen. Schauen Sie sich [CONTRIBUTING-DE.md](CONTRIBUTING-DE.md) an, wenn Sie Unterstützung beim Start brauchen.
[**FAQ**](https://github.com/rustdesk/rustdesk/wiki/FAQ)
@ -31,29 +31,29 @@ RustDesk heißt jegliche Mitarbeit willkommen. Schau dir [CONTRIBUTING-DE.md](CO
## Freie öffentliche Server
Nachfolgend sind die Server gelistet, die du kostenlos nutzen kannst. Es kann sein, dass sich diese Liste immer mal wieder ändert. Falls du nicht in der Nähe einer dieser Server bist, kann es sein, dass deine Verbindung langsam sein wird.
Nachfolgend sind die Server gelistet, die Sie kostenlos nutzen können. Es kann sein, dass sich diese Liste immer mal wieder ändert. Falls Sie nicht in der Nähe einer dieser Server sind, kann es sein, dass Ihre Verbindung langsam sein wird.
| Standort | Anbieter | Spezifikation |
| --------- | ------------- | ------------------ |
| Südkorea (Seoul) | AWS lightsail | 1 vCPU / 0,5 GB RAM |
| Deutschland | Hetzner | 2 vCPU / 4 GB RAM |
| Deutschland | Codext | 4 vCPU / 8 GB RAM |
| Finnland (Helsinki) | 0x101 Cyber Security | 4 vCPU / 8 GB RAM |
| USA (Ashburn) | 0x101 Cyber Security | 4 vCPU / 8 GB RAM |
| Ukraine (Kiew) | dc.volia (2VM) | 2 vCPU / 4 GB RAM |
| Südkorea (Seoul) | [AWS lightsail](https://aws.amazon.com/de/) | 1 vCPU / 0,5 GB RAM |
| Deutschland | [Hetzner](https://www.hetzner.com/de/) | 2 vCPU / 4 GB RAM |
| Deutschland | [Codext](https://codext.de/) | 4 vCPU / 8 GB RAM |
| Finnland (Helsinki) | [Netlock](https://netlockendpoint.com/de/index.html) | 4 vCPU / 8 GB RAM |
| USA (Ashburn) | [Netlock](https://netlockendpoint.com/de/index.html) | 4 vCPU / 8 GB RAM |
| Ukraine (Kiew) | [dc.volia](https://dc.volia.com) | 2 vCPU / 4 GB RAM |
## Dev-Container
[![In Dev-Containern öffnen](https://img.shields.io/static/v1?label=Dev%20Container&message=Open&color=blue&logo=visualstudiocode)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/rustdesk/rustdesk)
Wenn du VS Code und Docker bereits installiert hast, kannst du auf das Abzeichen oben klicken, um loszulegen. Wenn du darauf klickst, wird VS Code automatisch die Dev-Container-Erweiterung installieren, den Quellcode in ein Container-Volume klonen und einen Dev-Container für die Verwendung aufsetzen.
Wenn Sie VS Code und Docker bereits installiert haben, können Sie auf das Abzeichen oben klicken, um loszulegen. Wenn Sie darauf klicken, wird VS Code automatisch die Dev-Container-Erweiterung installieren, den Quellcode in ein Container-Volume klonen und einen Dev-Container für die Verwendung aufsetzen.
Weitere Informationen findest du in [DEVCONTAINER-DE.md](DEVCONTAINER-DE.md).
Weitere Informationen finden Sie in [DEVCONTAINER-DE.md](DEVCONTAINER-DE.md).
## Abhängigkeiten
Desktop-Versionen verwenden [Sciter](https://sciter.com/) oder Flutter für die GUI, dieses Tutorial ist nur für Sciter.
Bitte lade die dynamische Bibliothek Sciter selbst herunter.
Bitte laden Sie die dynamische Bibliothek Sciter selbst herunter.
[Windows](https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.win/x64/sciter.dll) |
[Linux](https://raw.githubusercontent.com/c-smile/sciter-sdk/master/bin.lnx/x64/libsciter-gtk.so) |
@ -61,14 +61,14 @@ Bitte lade die dynamische Bibliothek Sciter selbst herunter.
## Grobe Schritte zum Kompilieren
- Bereite deine Rust-Entwicklungsumgebung und C++-Build-Umgebung vor
- Bereiten Sie Ihre Rust-Entwicklungsumgebung und C++-Build-Umgebung vor
- Installiere [vcpkg](https://github.com/microsoft/vcpkg) und füge die Systemumgebungsvariable `VCPKG_ROOT` hinzu
- Installieren Sie [vcpkg](https://github.com/microsoft/vcpkg) und fügen Sie die Systemumgebungsvariable `VCPKG_ROOT` hinzu
- Windows: `vcpkg install libvpx:x64-windows-static libyuv:x64-windows-static opus:x64-windows-static`
- Linux/macOS: `vcpkg install libvpx libyuv opus`
- Nutze `cargo run`
- Nutzen Sie `cargo run`
## [Erstellen](https://rustdesk.com/docs/de/dev/build/)
@ -167,7 +167,7 @@ method return time=1662544486.931020 sender=:1.54 -> destination=:1.139 serial=2
## Auf Docker kompilieren
Beginne damit, das Repository zu klonen und den Docker-Container zu bauen:
Beginnen Sie damit, das Repository zu klonen und den Docker-Container zu bauen:
```sh
git clone https://github.com/rustdesk/rustdesk
@ -175,25 +175,25 @@ cd rustdesk
docker build -t "rustdesk-builder" .
```
Führe jedes Mal, wenn du das Programm kompilieren musst, folgenden Befehl aus:
Führen Sie jedes Mal, wenn Sie das Programm kompilieren müssen, folgenden Befehl aus:
```sh
docker run --rm -it -v $PWD:/home/user/rustdesk -v rustdesk-git-cache:/home/user/.cargo/git -v rustdesk-registry-cache:/home/user/.cargo/registry -e PUID="$(id -u)" -e PGID="$(id -g)" rustdesk-builder
```
Bedenke, dass das erste Kompilieren länger dauern kann, bis die Abhängigkeiten zwischengespeichert sind. Nachfolgende Kompiliervorgänge sind schneller. Wenn du verschiedene Argumente für den Kompilierbefehl angeben musst, kannst du dies am Ende des Befehls an der Position `<OPTIONAL-ARGS>` tun. Wenn du zum Beispiel eine optimierte Releaseversion kompilieren willst, kannst du `--release` am Ende des Befehls anhängen. Das daraus entstehende Programm findest du im Zielordner auf deinem System. Du kannst es mit folgendem Befehl ausführen:
Bedenken Sie, dass das erste Kompilieren länger dauern kann, bis die Abhängigkeiten zwischengespeichert sind. Nachfolgende Kompiliervorgänge sind schneller. Wenn Sie verschiedene Argumente für den Kompilierbefehl angeben müssen, können Sie dies am Ende des Befehls an der Position `<OPTIONAL-ARGS>` tun. Wenn Sie zum Beispiel eine optimierte Releaseversion kompilieren wollen, können Sie `--release` am Ende des Befehls anhängen. Das daraus entstehende Programm finden Sie im Zielordner auf Ihrem System. Sie können es mit folgendem Befehl ausführen:
```sh
target/debug/rustdesk
```
Oder, wenn du eine Releaseversion benutzt:
Oder, wenn Sie eine Releaseversion benutzen:
```sh
target/release/rustdesk
```
Bitte stelle sicher, dass du diese Befehle im Stammverzeichnis des RustDesk-Repositorys nutzt. Ansonsten kann es passieren, dass das Programm die Ressourcen nicht finden kann. Bitte bedenke auch, dass andere Cargo-Unterbefehle wie `install` oder `run` aktuell noch nicht unterstützt werden, da sie das Programm innerhalb des Containers starten oder installieren würden, anstatt auf deinem eigentlichen System.
Bitte stellen Sie sicher, dass Sie diese Befehle im Stammverzeichnis des RustDesk-Repositorys nutzen. Ansonsten kann es passieren, dass das Programm die Ressourcen nicht finden kann. Bitte bedenken Sie auch, dass andere Cargo-Unterbefehle wie `install` oder `run` aktuell noch nicht unterstützt werden, da sie das Programm innerhalb des Containers starten oder installieren würden, anstatt auf Ihrem eigentlichen System.
## Dateistruktur

View File

@ -623,7 +623,7 @@ class MainService : Service() {
.setAutoCancel(true)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentTitle(DEFAULT_NOTIFY_TITLE)
.setContentText(translate(DEFAULT_NOTIFY_TEXT) + '!')
.setContentText(translate(DEFAULT_NOTIFY_TEXT))
.setOnlyAlertOnce(true)
.setContentIntent(pendingIntent)
.setColor(ContextCompat.getColor(this, R.color.primary))
@ -689,7 +689,7 @@ class MainService : Service() {
private fun setTextNotification(_title: String?, _text: String?) {
val title = _title ?: DEFAULT_NOTIFY_TITLE
val text = _text ?: translate(DEFAULT_NOTIFY_TEXT) + '!'
val text = _text ?: translate(DEFAULT_NOTIFY_TEXT)
val notification = notificationBuilder
.clearActions()
.setStyle(null)

View File

@ -368,7 +368,7 @@ class MyTheme {
static void changeDarkMode(ThemeMode mode) async {
Get.changeThemeMode(mode);
if (desktopType == DesktopType.main) {
if (desktopType == DesktopType.main || isAndroid || isIOS) {
if (mode == ThemeMode.system) {
await bind.mainSetLocalOption(key: kCommConfKeyTheme, value: '');
} else {
@ -946,7 +946,6 @@ Widget msgboxContent(String type, String title, String text) {
void msgBoxCommon(OverlayDialogManager dialogManager, String title,
Widget content, List<Widget> buttons,
{bool hasCancel = true}) {
dialogManager.dismissAll();
dialogManager.show((setState, close) => CustomAlertDialog(
title: Text(
translate(title),

View File

@ -1130,7 +1130,7 @@ void _rdpDialog(String id) async {
}
return CustomAlertDialog(
title: Text('RDP ${translate('Settings')}'),
title: Text(translate('RDP Settings')),
content: ConstrainedBox(
constraints: const BoxConstraints(minWidth: 500),
child: Column(
@ -1141,56 +1141,67 @@ void _rdpDialog(String id) async {
),
Row(
children: [
ConstrainedBox(
constraints: const BoxConstraints(minWidth: 140),
child: Text(
"${translate('Port')}:",
textAlign: TextAlign.right,
).marginOnly(right: 10)),
isDesktop
? ConstrainedBox(
constraints: const BoxConstraints(minWidth: 140),
child: Text(
"${translate('Port')}:",
textAlign: TextAlign.right,
).marginOnly(right: 10))
: SizedBox.shrink(),
Expanded(
child: TextField(
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(
r'^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$'))
],
decoration: const InputDecoration(
border: OutlineInputBorder(), hintText: '3389'),
decoration: InputDecoration(
labelText: isDesktop ? null : translate('Port'),
border: isDesktop ? const OutlineInputBorder() : null,
hintText: '3389'),
controller: portController,
autofocus: true,
),
),
],
).marginOnly(bottom: 8),
).marginOnly(bottom: isDesktop ? 8 : 0),
Row(
children: [
ConstrainedBox(
constraints: const BoxConstraints(minWidth: 140),
child: Text(
"${translate('Username')}:",
textAlign: TextAlign.right,
).marginOnly(right: 10)),
isDesktop
? ConstrainedBox(
constraints: const BoxConstraints(minWidth: 140),
child: Text(
"${translate('Username')}:",
textAlign: TextAlign.right,
).marginOnly(right: 10))
: SizedBox.shrink(),
Expanded(
child: TextField(
decoration:
const InputDecoration(border: OutlineInputBorder()),
decoration: InputDecoration(
labelText: isDesktop ? null : translate('Username'),
border: isDesktop ? const OutlineInputBorder() : null),
controller: userController,
),
),
],
).marginOnly(bottom: 8),
).marginOnly(bottom: isDesktop ? 8 : 0),
Row(
children: [
ConstrainedBox(
constraints: const BoxConstraints(minWidth: 140),
child: Text(
"${translate('Password')}:",
textAlign: TextAlign.right,
).marginOnly(right: 10)),
isDesktop
? ConstrainedBox(
constraints: const BoxConstraints(minWidth: 140),
child: Text(
"${translate('Password')}:",
textAlign: TextAlign.right,
).marginOnly(right: 10))
: SizedBox.shrink(),
Expanded(
child: Obx(() => TextField(
obscureText: secure.value,
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: isDesktop ? null : translate('Password'),
border:
isDesktop ? const OutlineInputBorder() : null,
suffixIcon: IconButton(
onPressed: () => secure.value = !secure.value,
icon: Icon(secure.value
@ -1200,7 +1211,7 @@ void _rdpDialog(String id) async {
)),
),
],
).marginOnly(bottom: 8),
).marginOnly(bottom: isDesktop ? 8 : 0),
],
),
),

View File

@ -14,7 +14,10 @@ const String kPeerPlatformAndroid = "Android";
/// [kAppTypeMain] used by 'Desktop Main Page' , 'Mobile (Client and Server)', "Install Page"
const String kAppTypeMain = "main";
/// [kAppTypeConnectionManager] only for 'Desktop CM Page'
const String kAppTypeConnectionManager = "cm";
const String kAppTypeDesktopRemote = "remote";
const String kAppTypeDesktopFileTransfer = "file transfer";
const String kAppTypeDesktopPortForward = "port forward";

View File

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hbb/common.dart';
@ -63,6 +65,7 @@ class _InstallPageBodyState extends State<_InstallPageBody>
late final TextEditingController controller;
final RxBool startmenu = true.obs;
final RxBool desktopicon = true.obs;
final RxBool driverCert = true.obs;
final RxBool showProgress = false.obs;
final RxBool btnEnabled = true.obs;
@ -145,25 +148,62 @@ class _InstallPageBodyState extends State<_InstallPageBody>
.marginOnly(left: em))
],
).marginSymmetric(vertical: 2 * em),
Row(
children: [
Obx(() => Checkbox(
value: startmenu.value,
onChanged: (b) {
if (b != null) startmenu.value = b;
})),
Text(translate('Create start menu shortcuts'))
],
TextButton(
onPressed: () => startmenu.value = !startmenu.value,
child: Row(
children: [
Obx(() => Checkbox(
value: startmenu.value,
onChanged: (b) {
if (b != null) startmenu.value = b;
})),
RichText(
text: TextSpan(
text: translate('Create start menu shortcuts'),
style: DefaultTextStyle.of(context).style,
),
),
],
),
),
Row(
children: [
Obx(() => Checkbox(
value: desktopicon.value,
onChanged: (b) {
if (b != null) desktopicon.value = b;
})),
Text(translate('Create desktop icon'))
],
TextButton(
onPressed: () => desktopicon.value = !desktopicon.value,
child: Row(
children: [
Obx(() => Checkbox(
value: desktopicon.value,
onChanged: (b) {
if (b != null) desktopicon.value = b;
})),
RichText(
text: TextSpan(
text: translate('Create desktop icon'),
style: DefaultTextStyle.of(context).style,
),
),
],
),
),
Offstage(
offstage: !Platform.isWindows,
child: TextButton(
onPressed: () => driverCert.value = !driverCert.value,
child: Row(
children: [
Obx(() => Checkbox(
value: driverCert.value,
onChanged: (b) {
if (b != null) driverCert.value = b;
})),
RichText(
text: TextSpan(
text: translate('idd_driver_tip'),
style: DefaultTextStyle.of(context).style,
),
),
],
),
),
),
GestureDetector(
onTap: () => launchUrlString('http://rustdesk.com/privacy'),
@ -225,12 +265,47 @@ class _InstallPageBodyState extends State<_InstallPageBody>
}
void install() {
btnEnabled.value = false;
showProgress.value = true;
String args = '';
if (startmenu.value) args += ' startmenu';
if (desktopicon.value) args += ' desktopicon';
bind.installInstallMe(options: args, path: controller.text);
do_install() {
btnEnabled.value = false;
showProgress.value = true;
String args = '';
if (startmenu.value) args += ' startmenu';
if (desktopicon.value) args += ' desktopicon';
if (driverCert.value) args += ' driverCert';
bind.installInstallMe(options: args, path: controller.text);
}
if (driverCert.isTrue) {
final tag = 'install-info-install-cert-confirm';
final btns = [
dialogButton(
'Cancel',
onPressed: () => gFFI.dialogManager.dismissByTag(tag),
isOutline: true,
),
dialogButton(
'OK',
onPressed: () {
gFFI.dialogManager.dismissByTag(tag);
do_install();
},
isOutline: false,
),
];
gFFI.dialogManager.show(
(setState, close) => CustomAlertDialog(
title: null,
content: SelectionArea(
child:
msgboxContent('info', 'Warning', 'confirm_idd_driver_tip')),
actions: btns,
onCancel: close,
),
tag: tag,
);
} else {
do_install();
}
}
void selectInstallPath() async {

View File

@ -263,8 +263,11 @@ class ServerModel with ChangeNotifier {
toggleInput() {
if (_inputOk) {
parent.target?.invokeMethod("stop_input");
bind.mainSetOption(key: "enable-keyboard", value: 'N');
} else {
if (parent.target != null) {
/// the result of toggle-on depends on user actions in the settings page.
/// handle result, see [ServerModel.changeStatue]
showInputWarnAlert(parent.target!);
}
}

View File

@ -81,8 +81,10 @@ fn get_display_server_of_session(session: &str) -> String {
display_server = sestype;
}
}
// If the session is not a tty, then just return the type as usual
display_server
if display_server == "" {
display_server = "x11".to_owned();
}
display_server.to_lowercase()
}
pub fn get_values_of_seat0(indices: Vec<usize>) -> Vec<String> {

View File

@ -143,6 +143,10 @@ pub fn core_main() -> Option<Vec<String>> {
#[cfg(feature = "with_rc")]
hbb_common::allow_err!(crate::rc::extract_resources(&args[1]));
return None;
} else if args[0] == "--install-cert" {
#[cfg(windows)]
hbb_common::allow_err!(crate::platform::windows::install_cert(&args[1]));
return None;
} else if args[0] == "--portable-service" {
crate::platform::elevate_or_run_as_system(
click_setup,

View File

@ -26,8 +26,14 @@ use std::{
sync::{Arc, RwLock},
};
/// tag "main" for [Desktop Main Page] and [Mobile (Client and Server)] (the mobile don't need multiple windows, only one global event stream is needed)
/// tag "cm" only for [Desktop CM Page]
pub(super) const APP_TYPE_MAIN: &str = "main";
#[cfg(not(any(target_os = "android", target_os = "ios")))]
pub(super) const APP_TYPE_CM: &str = "cm";
#[cfg(any(target_os = "android", target_os = "ios"))]
pub(super) const APP_TYPE_CM: &str = "main";
pub(super) const APP_TYPE_DESKTOP_REMOTE: &str = "remote";
pub(super) const APP_TYPE_DESKTOP_FILE_TRANSFER: &str = "file transfer";
pub(super) const APP_TYPE_DESKTOP_PORT_FORWARD: &str = "port forward";

View File

@ -215,6 +215,7 @@ static mut IS_0X021D_DOWN: bool = false;
static mut IS_LEFT_OPTION_DOWN: bool = false;
pub fn start_grab_loop() {
std::env::set_var("KEYBOARD_ONLY", "y");
#[cfg(any(target_os = "windows", target_os = "macos"))]
std::thread::spawn(move || {
let try_handle_keyboard = move |event: Event, key: Key, is_press: bool| -> Option<Event> {

View File

@ -10,7 +10,7 @@ mod eo;
mod es;
mod fa;
mod fr;
mod gr;
mod el;
mod hu;
mod id;
mod it;
@ -59,7 +59,7 @@ pub const LANGS: &[(&str, &str)] = &[
("ua", "Українська"),
("fa", "فارسی"),
("ca", "Català"),
("gr", "Ελληνικά"),
("el", "Ελληνικά"),
("sv", "Svenska"),
("sq", "Shqip"),
("sr", "Srpski"),
@ -122,7 +122,7 @@ pub fn translate_locale(name: String, locale: &str) -> String {
"ua" => ua::T.deref(),
"fa" => fa::T.deref(),
"ca" => ca::T.deref(),
"gr" => gr::T.deref(),
"el" => el::T.deref(),
"sv" => sv::T.deref(),
"sq" => sq::T.deref(),
"sr" => sr::T.deref(),

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Avís"),
("Login screen using Wayland is not supported", "La pantalla d'inici de sessió amb Wayland no és compatible"),
("Reboot required", "Cal reiniciar"),
("Unsupported display server ", "Servidor de visualització no compatible"),
("Unsupported display server", "Servidor de visualització no compatible"),
("x11 expected", "x11 necessari"),
("Port", ""),
("Settings", "Ajustaments"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", ""),
("No transfers in progress", ""),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "警告"),
("Login screen using Wayland is not supported", "不支持使用 Wayland 登录界面"),
("Reboot required", "重启后才能生效"),
("Unsupported display server ", "不支持当前显示服务器"),
("Unsupported display server", "不支持当前显示服务器"),
("x11 expected", "请切换到 x11"),
("Port", "端口"),
("Settings", "设置"),
@ -349,7 +349,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Security", "安全"),
("Theme", "主题"),
("Dark Theme", "暗黑主题"),
("Light Theme", ""),
("Light Theme", "明亮主题"),
("Dark", "黑暗"),
("Light", "明亮"),
("Follow System", "跟随系统"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", "分辨率"),
("No transfers in progress", ""),
("Set one-time password length", ""),
("idd_driver_tip", "安装虚拟显示器驱动,以便在没有连接显示器的情况下启动虚拟显示器进行控制。"),
("confirm_idd_driver_tip", "安装虚拟显示器驱动的选项已勾选。请注意测试证书将被安装以信任虚拟显示器驱动。测试证书仅会用于信任Rustdesk的驱动。"),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Upozornení"),
("Login screen using Wayland is not supported", "Přihlašovací obrazovka prostřednictvím Wayland není podporována"),
("Reboot required", "Je třeba restartovat"),
("Unsupported display server ", "Nepodporovaný zobrazovací server"),
("Unsupported display server", "Nepodporovaný zobrazovací server"),
("x11 expected", "očekávány x11"),
("Port", ""),
("Settings", "Nastavení"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", ""),
("No transfers in progress", ""),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Advarsel"),
("Login screen using Wayland is not supported", "Registreringsskærm med Wayland understøttes ikke"),
("Reboot required", "Genstart krævet"),
("Unsupported display server ", "Ikke-understøttet displayserver"),
("Unsupported display server", "Ikke-understøttet displayserver"),
("x11 expected", "X11 Forventet"),
("Port", "Port"),
("Settings", "Indstillinger"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", ""),
("No transfers in progress", ""),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -152,7 +152,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Configure", "Konfigurieren"),
("config_acc", "Um Ihren PC aus der Ferne zu steuern, müssen Sie RustDesk Zugriffsrechte erteilen."),
("config_screen", "Um aus der Ferne auf Ihren PC zugreifen zu können, müssen Sie RustDesk die Berechtigung \"Bildschirmaufnahme\" erteilen."),
("Installing ...", " Wird installiert …"),
("Installing ...", "Wird installiert …"),
("Install", "Installieren"),
("Installation", "Installation"),
("Installation Path", "Installationspfad"),
@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Warnung"),
("Login screen using Wayland is not supported", "Anmeldebildschirm mit Wayland wird nicht unterstützt."),
("Reboot required", "Neustart erforderlich"),
("Unsupported display server ", "Nicht unterstützter Anzeigeserver"),
("Unsupported display server", "Nicht unterstützter Anzeigeserver"),
("x11 expected", "X11 erwartet"),
("Port", "Port"),
("Settings", "Einstellungen"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", "Auflösung"),
("No transfers in progress", "Keine Übertragungen im Gange"),
("Set one-time password length", "Länge des Einmalpassworts festlegen"),
("idd_driver_tip", "Installieren Sie den virtuellen Anzeigetreiber, der verwendet wird, wenn Sie keine physischen Anzeigen haben."),
("confirm_idd_driver_tip", "Die Option zur Installation des virtuellen Anzeigetreibers ist aktiviert. Beachten Sie, dass ein Testzertifikat installiert wird, um dem virtuellen Anzeigetreiber zu vertrauen. Dieses Testzertifikat wird nur verwendet, um Rustdesk-Treibern zu vertrauen."),
("RDP Settings", "RDP-Einstellungen"),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -24,7 +24,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Refresh random password", "Νέος τυχαίος κωδικός πρόσβασης"),
("Set your own password", "Ορίστε τον δικό σας κωδικό πρόσβασης"),
("Enable Keyboard/Mouse", "Ενεργοποίηση πληκτρολογίου/ποντικιού"),
("Enable Clipboard", "Ενεργοποίηση Προχείρου"),
("Enable Clipboard", "Ενεργοποίηση προχείρου"),
("Enable File Transfer", "Ενεργοποίηση μεταφοράς αρχείων"),
("Enable TCP Tunneling", "Ενεργοποίηση TCP Tunneling"),
("IP Whitelisting", "Λίστα επιτρεπόμενων IP"),
@ -44,7 +44,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("id_change_tip", "Επιτρέπονται μόνο οι χαρακτήρες a-z, A-Z, 0-9 και _ (υπογράμμιση). Το πρώτο γράμμα πρέπει να είναι a-z, A-Z και το μήκος πρέπει να είναι μεταξύ 6 και 16 χαρακτήρων."),
("Website", "Ιστότοπος"),
("About", "Πληροφορίες"),
("Slogan_tip", "Προγραμματισμένος με πάθος - σε έναν κόσμο που βυθίζεται στο χάος!"),
("Slogan_tip", "Φτιαγμένο με πάθος - σε έναν κόσμο που βυθίζεται στο χάος!"),
("Privacy Statement", "Πολιτική απορρήτου"),
("Mute", "Σίγαση"),
("Build Date", "Ημερομηνία δημιουργίας"),
@ -120,12 +120,12 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Original", "Πρωτότυπο"),
("Shrink", "Συρρίκνωση"),
("Stretch", "Προσαρμογή"),
("Scrollbar", "Γραμμή κύλισης"),
("Scrollbar", "Μπάρα κύλισης"),
("ScrollAuto", "Αυτόματη κύλιση"),
("Good image quality", "Καλή ποιότητα εικόνας"),
("Balanced", "Ισορροπημένο"),
("Optimize reaction time", "Βελτιστοποίηση χρόνου αντίδρασης"),
("Custom", "Προσαρμογή ποιότητας εικόνας"),
("Balanced", "Ισορροπημένη"),
("Optimize reaction time", "Βελτιστοποίηση απόκρισης"),
("Custom", "Προσαρμοσμένη ποιότητας εικόνας"),
("Show remote cursor", "Εμφάνιση απομακρυσμένου κέρσορα"),
("Show quality monitor", "Εμφάνιση παρακολούθησης ποιότητας σύνδεσης"),
("Disable clipboard", "Απενεργοποίηση προχείρου"),
@ -146,9 +146,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Set Password", "Ορίστε κωδικό πρόσβασης"),
("OS Password", "Κωδικός πρόσβασης λειτουργικού συστήματος"),
("install_tip", "Λόγω UAC, το RustDesk ενδέχεται να μην λειτουργεί σωστά σε ορισμένες περιπτώσεις. Για να αποφύγετε το UAC, κάντε κλικ στο κουμπί παρακάτω για να εγκαταστήσετε το RustDesk στο σύστημα"),
("Click to upgrade", "Κάντε κλικ για αναβάθμιση"),
("Click to download", "Κάντε κλικ για λήψη"),
("Click to update", "Κάντε κλικ για ενημέρωση"),
("Click to upgrade", "Πιέστε για αναβάθμιση"),
("Click to download", "Πιέστε για λήψη"),
("Click to update", "Πιέστε για ενημέρωση"),
("Configure", "Διαμόρφωση"),
("config_acc", "Για τον απομακρυσμένο έλεγχο του υπολογιστή σας, πρέπει να εκχωρήσετε δικαιώματα πρόσβασης στο RustDesk."),
("config_screen", "Για να αποκτήσετε απομακρυσμένη πρόσβαση στον υπολογιστή σας, πρέπει να εκχωρήσετε το δικαίωμα RustDesk \"Screen Capture\"."),
@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Προειδοποίηση"),
("Login screen using Wayland is not supported", "Η οθόνη εισόδου με χρήση του Wayland δεν υποστηρίζεται"),
("Reboot required", "Απαιτείται επανεκκίνηση"),
("Unsupported display server ", "Μη υποστηριζόμενος διακομιστής εμφάνισης "),
("Unsupported display server", "Μη υποστηριζόμενος διακομιστής εμφάνισης "),
("x11 expected", "απαιτείται X11"),
("Port", "Θύρα"),
("Settings", "Ρυθμίσεις"),
@ -242,7 +242,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Invalid folder name", "Μη έγκυρο όνομα φακέλου"),
("Socks5 Proxy", "Διαμεσολαβητής Socks5"),
("Hostname", "Όνομα υπολογιστή"),
("Discovered", "Ανακαλύφθηκε"),
("Discovered", "Ανακαλύφθηκαν"),
("install_daemon_tip", "Για να ξεκινά με την εκκίνηση του υπολογιστή, πρέπει να εγκαταστήσετε την υπηρεσία συστήματος"),
("Remote ID", "Απομακρυσμένο ID"),
("Paste", "Επικόλληση"),
@ -344,7 +344,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Secure Connection", "Ασφαλής σύνδεση"),
("Insecure Connection", "Μη ασφαλής σύνδεση"),
("Scale original", "Κλιμάκωση πρωτότυπου"),
("Scale adaptive", "Προσαρμοστική κλίμακα"),
("Scale adaptive", "Προσαρμοσμένη κλίμακα"),
("General", "Γενικά"),
("Security", "Ασφάλεια"),
("Theme", "Θέμα"),
@ -460,7 +460,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Codec", "Κωδικοποίηση"),
("Resolution", "Ανάλυση"),
("No transfers in progress", "Δεν υπάρχει μεταφορά σε εξέλιξη"),
("Set one-time password length", ""),
("Set one-time password length", "Μέγεθος κωδικού μιας χρήσης"),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -45,5 +45,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("config_microphone", "In order to speak remotely, you need to grant RustDesk \"Record Audio\" permissions."),
("relay_hint_tip", "It may not be possible to connect directly, you can try to connect via relay. \nIn addition, if you want to use relay on your first try, you can add the \"/r\" suffix to the ID, or select the option \"Always connect via relay\" in the peer card."),
("No transfers in progress", ""),
("idd_driver_tip", "Install virtual display driver which is used when you have no physical displays."),
("confirm_idd_driver_tip", "The option to install the virtual display driver is checked. Note that a test certificate will be installed to trust the virtual display driver. This test certificate will only be used to trust Rustdesk drivers.")
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Averto"),
("Login screen using Wayland is not supported", "Konektajn ekranojn uzantajn Wayland ne estas subtenitaj"),
("Reboot required", "Restarto deviga"),
("Unsupported display server ", "La aktuala bilda servilo ne estas subtenita"),
("Unsupported display server", "La aktuala bilda servilo ne estas subtenita"),
("x11 expected", "Bonvolu uzi x11"),
("Port", ""),
("Settings", "Agordoj"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", ""),
("No transfers in progress", ""),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Aviso"),
("Login screen using Wayland is not supported", "La pantalla de inicio de sesión con Wayland no es compatible"),
("Reboot required", "Reinicio requerido"),
("Unsupported display server ", "Servidor de visualización no compatible"),
("Unsupported display server", "Servidor de visualización no compatible"),
("x11 expected", "x11 necesario"),
("Port", "Puerto"),
("Settings", "Ajustes"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", "Resolución"),
("No transfers in progress", "No hay transferencias en curso"),
("Set one-time password length", "Establecer contraseña de un solo uso"),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "هشدار"),
("Login screen using Wayland is not supported", "پشتیبانی نمی شود Wayland ورود به سیستم با استفاده از "),
("Reboot required", "راه اندازی مجدد مورد نیاز است"),
("Unsupported display server ", "سرور تصویر پشتیبانی نشده است"),
("Unsupported display server", "سرور تصویر پشتیبانی نشده است"),
("x11 expected", ""),
("Port", "پورت"),
("Settings", "تنظیمات"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", "وضوح"),
("No transfers in progress", "هیچ انتقالی در حال انجام نیست"),
("Set one-time password length", "طول رمز یکبار مصرف را تعیین کنید"),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Avertissement"),
("Login screen using Wayland is not supported", "L'écran de connexion utilisant Wayland n'est pas pris en charge"),
("Reboot required", "Redémarrage requis"),
("Unsupported display server ", "Le serveur d'affichage actuel n'est pas pris en charge"),
("Unsupported display server", "Le serveur d'affichage actuel n'est pas pris en charge"),
("x11 expected", "x11 requis"),
("Port", "Port"),
("Settings", "Paramètres"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", ""),
("No transfers in progress", ""),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Figyelmeztetés"),
("Login screen using Wayland is not supported", "Bejelentkezéskori Wayland használata nem támogatott"),
("Reboot required", "Újraindítás szükséges"),
("Unsupported display server ", "Nem támogatott megjelenítő szerver"),
("Unsupported display server", "Nem támogatott megjelenítő szerver"),
("x11 expected", "x11-re számítottt"),
("Port", "Port"),
("Settings", "Beállítások"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", ""),
("No transfers in progress", ""),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Peringatan"),
("Login screen using Wayland is not supported", "Layar masuk menggunakan Wayland tidak didukung"),
("Reboot required", "Diperlukan boot ulang"),
("Unsupported display server ", "Server tampilan tidak didukung "),
("Unsupported display server", "Server tampilan tidak didukung "),
("x11 expected", "x11 diharapkan"),
("Port", "Port"),
("Settings", "Pengaturan"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", ""),
("No transfers in progress", ""),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Avviso"),
("Login screen using Wayland is not supported", "La schermata di accesso non è supportata utilizzando Wayland"),
("Reboot required", "Riavvio necessario"),
("Unsupported display server ", "Display server non supportato"),
("Unsupported display server", "Display server non supportato"),
("x11 expected", "x11 necessario"),
("Port", "Porta"),
("Settings", "Impostazioni"),
@ -460,7 +460,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Codec", "Codec"),
("Resolution", "Risoluzione"),
("No transfers in progress", "Nessun trasferimento in corso"),
("Set one-time password length", "Imposta lunghezza password monouso"),
("Set one-time password length", "Imposta la lunghezza della password monouso"),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", "Imposta lunghezza password monouso"),
("Sort by", "Ordina per"),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "注意"),
("Login screen using Wayland is not supported", "Waylandを使用したログインスクリーンはサポートされていません"),
("Reboot required", "再起動が必要"),
("Unsupported display server ", "サポートされていないディスプレイサーバー"),
("Unsupported display server", "サポートされていないディスプレイサーバー"),
("x11 expected", "X11 が必要です"),
("Port", ""),
("Settings", "設定"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", ""),
("No transfers in progress", ""),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "경고"),
("Login screen using Wayland is not supported", "Wayland를 사용한 로그인 화면이 지원되지 않습니다"),
("Reboot required", "재부팅이 필요합니다"),
("Unsupported display server ", "지원하지 않는 디스플레이 서버"),
("Unsupported display server", "지원하지 않는 디스플레이 서버"),
("x11 expected", "x11 예상됨"),
("Port", ""),
("Settings", "설정"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", ""),
("No transfers in progress", ""),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Ескерту"),
("Login screen using Wayland is not supported", "Wayland қолданған Кіру екіреніне қолдау көрсетілмейді"),
("Reboot required", "Қайта-қосу қажет"),
("Unsupported display server ", "Қолдаусыз дисплей сербері"),
("Unsupported display server", "Қолдаусыз дисплей сербері"),
("x11 expected", "x11 күтілген"),
("Port", "Порт"),
("Settings", "Орнатпалар"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", ""),
("No transfers in progress", ""),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Waarschuwing"),
("Login screen using Wayland is not supported", "Aanmeldingsscherm via Wayland wordt niet ondersteund"),
("Reboot required", "Opnieuw opstarten vereist"),
("Unsupported display server ", "Niet-ondersteunde weergaveserver"),
("Unsupported display server", "Niet-ondersteunde weergaveserver"),
("x11 expected", "x11 verwacht"),
("Port", "Poort"),
("Settings", "Instellingen"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", "Resolutie"),
("No transfers in progress", "Geen overdrachten in uitvoering"),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Ostrzeżenie"),
("Login screen using Wayland is not supported", "Ekran logowania korzystający z Wayland nie jest obsługiwany"),
("Reboot required", "Wymagany ponowne uruchomienie"),
("Unsupported display server ", "Nieobsługiwany serwer wyświetlania"),
("Unsupported display server", "Nieobsługiwany serwer wyświetlania"),
("x11 expected", "Wymagany jest X11"),
("Port", "Port"),
("Settings", "Ustawienia"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", "Rozdzielczość"),
("No transfers in progress", "Brak transferów w toku"),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Aviso"),
("Login screen using Wayland is not supported", "Tela de Login com Wayland não é suportada"),
("Reboot required", "Reinicialização necessária"),
("Unsupported display server ", "Servidor de display não suportado"),
("Unsupported display server", "Servidor de display não suportado"),
("x11 expected", "x11 em falha"),
("Port", ""),
("Settings", "Configurações"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", ""),
("No transfers in progress", ""),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Aviso"),
("Login screen using Wayland is not supported", "Tela de Login utilizando Wayland não é suportada"),
("Reboot required", "Reinicialização necessária"),
("Unsupported display server ", "Servidor de display não suportado"),
("Unsupported display server", "Servidor de display não suportado"),
("x11 expected", "x11 esperado"),
("Port", "Porta"),
("Settings", "Configurações"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", ""),
("No transfers in progress", ""),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Avertisment"),
("Login screen using Wayland is not supported", "Ecranele de conectare care folosesc Wayland nu sunt acceptate"),
("Reboot required", "Repornire necesară"),
("Unsupported display server ", "Tipul de server de afișaj nu este acceptat"),
("Unsupported display server", "Tipul de server de afișaj nu este acceptat"),
("x11 expected", "E necesar X11"),
("Port", "Port"),
("Settings", "Setări"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", ""),
("No transfers in progress", ""),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Предупреждение"),
("Login screen using Wayland is not supported", "Вход в систему с использованием Wayland не поддерживается"),
("Reboot required", "Требуется перезагрузка"),
("Unsupported display server ", "Неподдерживаемый сервер отображения"),
("Unsupported display server", "Неподдерживаемый сервер отображения"),
("x11 expected", "Ожидается X11"),
("Port", "Порт"),
("Settings", "Настройки"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", "Разрешение"),
("No transfers in progress", "Передача не осуществляется"),
("Set one-time password length", "Установить длину одноразового пароля"),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Upozornenie"),
("Login screen using Wayland is not supported", "Prihlasovacia obrazovka prostredníctvom Wayland nie je podporovaná"),
("Reboot required", "Vyžaduje sa reštart"),
("Unsupported display server ", "Nepodporovaný zobrazovací (display) server"),
("Unsupported display server", "Nepodporovaný zobrazovací (display) server"),
("x11 expected", "očakáva sa x11"),
("Port", ""),
("Settings", "Nastavenia"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", ""),
("No transfers in progress", ""),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Opozorilo"),
("Login screen using Wayland is not supported", "Prijava z Waylandom ni podprta"),
("Reboot required", "Potreben je ponovni zagon"),
("Unsupported display server ", "Nepodprt zaslonski strežnik"),
("Unsupported display server", "Nepodprt zaslonski strežnik"),
("x11 expected", "Pričakovan X11"),
("Port", "Vrata"),
("Settings", "Nastavitve"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", ""),
("No transfers in progress", ""),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Dicka po shkon keq"),
("Login screen using Wayland is not supported", "Hyrja në ekran duke përdorur Wayland muk suportohet"),
("Reboot required", "Kërkohet rinisja"),
("Unsupported display server ", "Nuk supurtohet severi ekranit"),
("Unsupported display server", "Nuk supurtohet severi ekranit"),
("x11 expected", "Pritet x11"),
("Port", "Port"),
("Settings", "Cilësimet"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", ""),
("No transfers in progress", ""),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Upozorenje"),
("Login screen using Wayland is not supported", "Ekran za prijavu koji koristi Wayland nije podržan"),
("Reboot required", "Potreban je restart"),
("Unsupported display server ", "Nepodržan server za prikaz"),
("Unsupported display server", "Nepodržan server za prikaz"),
("x11 expected", "x11 očekivan"),
("Port", "Port"),
("Settings", "Postavke"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", ""),
("No transfers in progress", ""),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Varning"),
("Login screen using Wayland is not supported", "Login med Wayland stöds inte"),
("Reboot required", "Omstart krävs"),
("Unsupported display server ", "Displayserver stöds inte "),
("Unsupported display server", "Displayserver stöds inte "),
("x11 expected", "x11 förväntades"),
("Port", "Port"),
("Settings", "Inställningar"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", ""),
("No transfers in progress", ""),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", ""),
("Login screen using Wayland is not supported", ""),
("Reboot required", ""),
("Unsupported display server ", ""),
("Unsupported display server", ""),
("x11 expected", ""),
("Port", ""),
("Settings", ""),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", ""),
("No transfers in progress", ""),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "คำเตือน"),
("Login screen using Wayland is not supported", "หน้าจอการเข้าสู่ระบบโดยใช้ Wayland ยังไม่ถูกรองรับ"),
("Reboot required", "จำเป็นต้องเริ่มต้นระบบใหม่"),
("Unsupported display server ", "เซิร์ฟเวอร์การแสดงผลที่ไม่รองรับ"),
("Unsupported display server", "เซิร์ฟเวอร์การแสดงผลที่ไม่รองรับ"),
("x11 expected", "ต้องใช้งาน x11"),
("Port", "พอร์ท"),
("Settings", "ตั้งค่า"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", ""),
("No transfers in progress", ""),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Uyarı"),
("Login screen using Wayland is not supported", "Wayland kullanan giriş ekranı desteklenmiyor"),
("Reboot required", "Yeniden başlatma gerekli"),
("Unsupported display server ", "Desteklenmeyen görüntü sunucusu"),
("Unsupported display server", "Desteklenmeyen görüntü sunucusu"),
("x11 expected", "x11 bekleniyor"),
("Port", "Port"),
("Settings", "Ayarlar"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", ""),
("No transfers in progress", ""),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "警告"),
("Login screen using Wayland is not supported", "不支援使用 Wayland 的登入畫面"),
("Reboot required", "需要重新啟動"),
("Unsupported display server ", "不支援顯示伺服器"),
("Unsupported display server", "不支援顯示伺服器"),
("x11 expected", "預期 x11"),
("Port", "端口"),
("Settings", "設定"),
@ -349,7 +349,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Security", "安全"),
("Theme", "主題"),
("Dark Theme", "暗黑主題"),
("Light Theme", ""),
("Light Theme", "明亮主題"),
("Dark", "黑暗"),
("Light", "明亮"),
("Follow System", "跟隨系統"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", "分辨率"),
("No transfers in progress", ""),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Попередження"),
("Login screen using Wayland is not supported", "Вхід у систему з використанням Wayland не підтримується"),
("Reboot required", "Потрібне перезавантаження"),
("Unsupported display server ", "Графічний сервер не підтримується"),
("Unsupported display server", "Графічний сервер не підтримується"),
("x11 expected", "Очікується X11"),
("Port", "Порт"),
("Settings", "Налаштування"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", ""),
("No transfers in progress", ""),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -204,7 +204,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Warning", "Cảnh báo"),
("Login screen using Wayland is not supported", "Màn hình đăng nhập sử dụng Wayland không đựoc hỗ trợ"),
("Reboot required", "Yêu cầu khởi động lại"),
("Unsupported display server ", "Máy chủ hiển thị không đuợc hỗ trọ"),
("Unsupported display server", "Máy chủ hiển thị không đuợc hỗ trọ"),
("x11 expected", "Cần x11"),
("Port", ""),
("Settings", "Cài đặt"),
@ -461,6 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Resolution", ""),
("No transfers in progress", ""),
("Set one-time password length", ""),
("idd_driver_tip", ""),
("confirm_idd_driver_tip", ""),
("RDP Settings", ""),
("Sort by", ""),
].iter().cloned().collect();
}

View File

@ -1108,6 +1108,12 @@ if exist \"{tmp_path}\\{app_name} Tray.lnk\" del /f /q \"{tmp_path}\\{app_name}
);
let src_exe = std::env::current_exe()?.to_str().unwrap_or("").to_string();
let install_cert = if options.contains("driverCert") {
format!("\"{}\" --install-cert \"RustDeskIddDriver.cer\"", src_exe)
} else {
"".to_owned()
};
let cmds = format!(
"
{uninstall_str}
@ -1139,6 +1145,7 @@ sc create {app_name} binpath= \"\\\"{exe}\\\" --import-config \\\"{config_path}\
sc start {app_name}
sc stop {app_name}
sc delete {app_name}
{install_cert}
{after_install}
{sleep}
",
@ -1159,6 +1166,7 @@ sc delete {app_name}
shortcuts=shortcuts,
config_path=Config::file().to_str().unwrap_or(""),
lic=register_licence(),
install_cert=install_cert,
after_install=get_after_install(&exe),
sleep=if debug {
"timeout 300"
@ -1236,6 +1244,7 @@ fn get_uninstall(kill_self: bool) -> String {
}
pub fn uninstall_me(kill_self: bool) -> ResultType<()> {
allow_err!(cert::uninstall_certs());
run_cmds(get_uninstall(kill_self), true, "uninstall")
}
@ -1902,3 +1911,177 @@ pub fn user_accessible_folder() -> ResultType<PathBuf> {
}
Ok(dir)
}
#[inline]
pub fn install_cert(cert_file: &str) -> ResultType<()> {
let exe_file = std::env::current_exe()?;
if let Some(cur_dir) = exe_file.parent() {
allow_err!(cert::install_cert(cur_dir.join(cert_file)));
} else {
bail!(
"Invalid exe parent for {}",
exe_file.to_string_lossy().as_ref()
);
}
Ok(())
}
mod cert {
use hbb_common::{allow_err, bail, log, ResultType};
use std::{path::Path, str::from_utf8};
use winapi::shared::{
minwindef::{BYTE, DWORD, TRUE},
ntdef::NULL,
};
use winapi::um::{
errhandlingapi::GetLastError,
wincrypt::{
CertCloseStore, CertEnumCertificatesInStore, CertNameToStrA, CertOpenSystemStoreA,
CryptHashCertificate, ALG_ID, CALG_SHA1, CERT_ID_SHA1_HASH, CERT_X500_NAME_STR,
PCCERT_CONTEXT,
},
winreg::HKEY_LOCAL_MACHINE,
};
use winreg::{
enums::{KEY_WRITE, REG_BINARY},
RegKey,
};
const ROOT_CERT_STORE_PATH: &str = "SOFTWARE\\Microsoft\\SystemCertificates\\ROOT\\Certificates\\";
const THUMBPRINT_ALG: ALG_ID = CALG_SHA1;
const THUMBPRINT_LEN: DWORD = 20;
#[inline]
unsafe fn compute_thumbprint(pb_encoded: *const BYTE, cb_encoded: DWORD) -> (Vec<u8>, String) {
let mut size = THUMBPRINT_LEN;
let mut thumbprint = [0u8; THUMBPRINT_LEN as usize];
if CryptHashCertificate(
0,
THUMBPRINT_ALG,
0,
pb_encoded,
cb_encoded,
thumbprint.as_mut_ptr(),
&mut size,
) == TRUE
{
(thumbprint.to_vec(), hex::encode(thumbprint).to_ascii_uppercase())
} else {
(thumbprint.to_vec(), "".to_owned())
}
}
#[inline]
unsafe fn open_reg_cert_store() -> ResultType<RegKey> {
let hklm = winreg::RegKey::predef(HKEY_LOCAL_MACHINE);
Ok(hklm.open_subkey_with_flags(ROOT_CERT_STORE_PATH, KEY_WRITE)?)
}
// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-gpef/6a9e35fa-2ac7-4c10-81e1-eabe8d2472f1
fn create_cert_blob(thumbprint: Vec<u8>, encoded: Vec<u8>) -> Vec<u8> {
let mut blob = Vec::new();
let mut property_id = (CERT_ID_SHA1_HASH as u32).to_le_bytes().to_vec();
let mut pro_reserved = [0x01, 0x00, 0x00, 0x00].to_vec();
let mut pro_length = (THUMBPRINT_LEN as u32).to_le_bytes().to_vec();
let mut pro_val = thumbprint;
blob.append(&mut property_id);
blob.append(&mut pro_reserved);
blob.append(&mut pro_length);
blob.append(&mut pro_val);
let mut blob_reserved = [0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00].to_vec();
let mut blob_length = (encoded.len() as u32).to_le_bytes().to_vec();
let mut blob_val = encoded;
blob.append(&mut blob_reserved);
blob.append(&mut blob_length);
blob.append(&mut blob_val);
blob
}
pub fn install_cert<P: AsRef<Path>>(path: P) -> ResultType<()> {
let mut cert_bytes = std::fs::read(path)?;
unsafe {
let thumbprint = compute_thumbprint(cert_bytes.as_mut_ptr(), cert_bytes.len() as _);
log::debug!("Thumbprint of cert {}", &thumbprint.1);
let reg_cert_key = open_reg_cert_store()?;
let (cert_key, _) = reg_cert_key.create_subkey(&thumbprint.1)?;
let data = winreg::RegValue {
vtype: REG_BINARY,
bytes: create_cert_blob(thumbprint.0, cert_bytes),
};
cert_key.set_raw_value("Blob", &data)?;
}
Ok(())
}
fn get_thumbprints_to_rm() -> ResultType<Vec<String>> {
let issuers_to_rm = ["CN=\"WDKTestCert admin,133225435702113567\""];
let mut thumbprints = Vec::new();
let mut buf = [0u8; 1024];
unsafe {
let store_handle = CertOpenSystemStoreA(0 as _, "ROOT\0".as_ptr() as _);
if store_handle.is_null() {
bail!("Error opening certificate store: {}", GetLastError());
}
let mut cert_ctx: PCCERT_CONTEXT = CertEnumCertificatesInStore(store_handle, NULL as _);
while !cert_ctx.is_null() {
// https://stackoverflow.com/a/66432736
let cb_size = CertNameToStrA(
(*cert_ctx).dwCertEncodingType,
&mut ((*(*cert_ctx).pCertInfo).Issuer) as _,
CERT_X500_NAME_STR,
buf.as_mut_ptr() as _,
buf.len() as _,
);
if cb_size != 1 {
if let Ok(issuer) = from_utf8(&buf[..cb_size as _]) {
for iss in issuers_to_rm.iter() {
if issuer.contains(iss) {
let (_, thumbprint) = compute_thumbprint(
(*cert_ctx).pbCertEncoded,
(*cert_ctx).cbCertEncoded,
);
if !thumbprint.is_empty() {
thumbprints.push(thumbprint);
}
}
}
}
}
cert_ctx = CertEnumCertificatesInStore(store_handle, cert_ctx);
}
CertCloseStore(store_handle, 0);
}
Ok(thumbprints)
}
pub fn uninstall_certs() -> ResultType<()> {
let thumbprints = get_thumbprints_to_rm()?;
let reg_cert_key = unsafe { open_reg_cert_store()? };
for thumbprint in thumbprints.iter() {
allow_err!(reg_cert_key.delete_subkey(thumbprint));
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_install_cert() {
println!("install driver cert: {:?}", cert::install_cert("RustDeskIddDriver.cer"));
}
#[test]
fn test_uninstall_cert() {
println!("uninstall driver certs: {:?}", cert::uninstall_certs());
}
}

View File

@ -511,7 +511,7 @@ pub fn get_error() -> String {
if dtype != "x11" {
return format!(
"{} {}, {}",
crate::client::translate("Unsupported display server ".to_owned()),
crate::client::translate("Unsupported display server".to_owned()),
dtype,
crate::client::translate("x11 expected".to_owned()),
);