From b14f4574747ea34aa54330607913749c6604e76e Mon Sep 17 00:00:00 2001 From: 21pages Date: Sat, 22 Oct 2022 12:03:57 +0800 Subject: [PATCH 1/4] auto new line && add server conf export Signed-off-by: 21pages --- .../lib/desktop/pages/connection_page.dart | 45 +- .../desktop/pages/desktop_setting_page.dart | 658 +++++++----------- src/lang/cn.rs | 4 +- src/lang/cs.rs | 4 +- src/lang/da.rs | 4 +- src/lang/de.rs | 4 +- src/lang/eo.rs | 4 +- src/lang/es.rs | 4 +- src/lang/fr.rs | 4 +- src/lang/hu.rs | 4 +- src/lang/id.rs | 4 +- src/lang/it.rs | 4 +- src/lang/ja.rs | 4 +- src/lang/ko.rs | 4 +- src/lang/kz.rs | 4 +- src/lang/pl.rs | 4 +- src/lang/pt_PT.rs | 4 +- src/lang/ptbr.rs | 4 +- src/lang/ru.rs | 4 +- src/lang/sk.rs | 4 +- src/lang/template.rs | 4 +- src/lang/tr.rs | 4 +- src/lang/tw.rs | 5 +- src/lang/ua.rs | 4 +- src/lang/vn.rs | 4 +- 25 files changed, 351 insertions(+), 445 deletions(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 8964191f8..30b685347 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -282,23 +282,34 @@ class _ConnectionPageState extends State .marginOnly(left: em), ), // ready && public - Offstage( - offstage: !(!svcStopped.value && - svcStatusCode.value == 1 && - svcIsUsingPublicServer.value), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text(', ', style: TextStyle(fontSize: em)), - InkWell( - onTap: onUsePublicServerGuide, - child: Text( - translate('setup_server_tip'), - style: TextStyle( - decoration: TextDecoration.underline, fontSize: em), - ), - ) - ], + Flexible( + child: Offstage( + offstage: !(!svcStopped.value && + svcStatusCode.value == 1 && + svcIsUsingPublicServer.value), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text(', ', style: TextStyle(fontSize: em)), + Flexible( + child: InkWell( + onTap: onUsePublicServerGuide, + child: Row( + children: [ + Flexible( + child: Text( + translate('setup_server_tip'), + style: TextStyle( + decoration: TextDecoration.underline, + fontSize: em), + ), + ), + ], + ), + ), + ) + ], + ), ), ) ], diff --git a/flutter/lib/desktop/pages/desktop_setting_page.dart b/flutter/lib/desktop/pages/desktop_setting_page.dart index 23d832580..22247c033 100644 --- a/flutter/lib/desktop/pages/desktop_setting_page.dart +++ b/flutter/lib/desktop/pages/desktop_setting_page.dart @@ -321,6 +321,7 @@ class _GeneralState extends State<_General> { ...devices.map((device) => _Radio(context, value: device, groupValue: currentDevice, + autoNewLine: false, label: device, onChanged: (value) { setDevice(value); setState(() {}); @@ -812,11 +813,7 @@ class _NetworkState extends State<_Network> with AutomaticKeepAliveClientMixin { AbsorbPointer( absorbing: locked, child: Column(children: [ - _CardRow(title: 'Server', children: [ - _Button('ID/Relay Server', changeServer, enabled: enabled), - _Button('Import Server Conf', importServer, - enabled: enabled), - ]), + server(enabled), _Card(title: 'Proxy', children: [ _Button('Socks5 Proxy', changeSocks5Proxy, enabled: enabled), @@ -825,6 +822,156 @@ class _NetworkState extends State<_Network> with AutomaticKeepAliveClientMixin { ), ]).marginOnly(bottom: _kListViewBottomMargin)); } + + server(bool enabled) { + return _futureBuilder(future: () async { + return await bind.mainGetOptions(); + }(), hasData: (data) { + // Setting page is not modal, oldOptions should only be used when getting options, never when setting. + Map oldOptions = jsonDecode(data! as String); + old(String key) { + return (oldOptions[key] ?? "").trim(); + } + + RxString idErrMsg = "".obs; + RxString relayErrMsg = "".obs; + RxString apiErrMsg = "".obs; + var idController = + TextEditingController(text: old('custom-rendezvous-server')); + var relayController = TextEditingController(text: old('relay-server')); + var apiController = TextEditingController(text: old('api-server')); + var keyController = TextEditingController(text: old('key')); + + set(String idServer, String relayServer, String apiServer, + String key) async { + idServer = idServer.trim(); + relayServer = relayServer.trim(); + apiServer = apiServer.trim(); + key = key.trim(); + if (idServer.isNotEmpty) { + idErrMsg.value = + translate(await bind.mainTestIfValidServer(server: idServer)); + if (idErrMsg.isNotEmpty) { + return false; + } + } + if (relayServer.isNotEmpty) { + relayErrMsg.value = + translate(await bind.mainTestIfValidServer(server: relayServer)); + if (relayErrMsg.isNotEmpty) { + return false; + } + } + if (apiServer.isNotEmpty) { + if (!apiServer.startsWith('http://') || + !apiServer.startsWith("https://")) { + apiErrMsg.value = + "${translate("API Server")}: ${translate("invalid_http")}"; + return false; + } + } + // should set one by one + await bind.mainSetOption( + key: 'custom-rendezvous-server', value: idServer); + await bind.mainSetOption(key: 'relay-server', value: relayServer); + await bind.mainSetOption(key: 'api-server', value: apiServer); + await bind.mainSetOption(key: 'key', value: key); + return true; + } + + submit() async { + bool result = await set(idController.text, relayController.text, + apiController.text, keyController.text); + if (result) { + setState(() {}); + showToast(translate('Successful')); + } else { + showToast(translate('Failed')); + } + } + + import() { + Clipboard.getData(Clipboard.kTextPlain).then((value) { + TextEditingController mytext = TextEditingController(); + String? aNullableString = ""; + aNullableString = value?.text; + mytext.text = aNullableString.toString(); + if (mytext.text.isNotEmpty) { + try { + Map config = jsonDecode(mytext.text); + if (config.containsKey('IdServer')) { + String id = config['IdServer'] ?? ''; + String relay = config['RelayServer'] ?? ''; + String api = config['ApiServer'] ?? ''; + String key = config['Key'] ?? ''; + idController.text = id; + relayController.text = relay; + apiController.text = api; + keyController.text = key; + Future success = set(id, relay, api, key); + success.then((value) { + if (value) { + showToast( + translate('Import server configuration successfully')); + } else { + showToast(translate('Invalid server configuration')); + } + }); + } else { + showToast(translate("Invalid server configuration")); + } + } catch (e) { + showToast(translate("Invalid server configuration")); + } + } else { + showToast(translate("Clipboard is empty")); + } + }); + } + + export() { + Map config = {}; + config['IdServer'] = idController.text.trim(); + config['RelayServer'] = relayController.text.trim(); + config['ApiServer'] = apiController.text.trim(); + config['Key'] = keyController.text.trim(); + Clipboard.setData(ClipboardData(text: jsonEncode(config))); + showToast(translate("Export server configuration successfully")); + } + + bool secure = !enabled; + return _Card(title: 'ID/Relay Server', title_suffix: [ + Tooltip( + message: translate('Import Server Config'), + child: IconButton( + icon: Icon(Icons.paste, color: Colors.grey), + onPressed: enabled ? import : null), + ), + Tooltip( + message: translate('Export Server Config'), + child: IconButton( + icon: Icon(Icons.copy, color: Colors.grey), + onPressed: enabled ? export : null)), + ], children: [ + Column( + children: [ + Obx(() => _LabeledTextField(context, 'ID Server', idController, + idErrMsg.value, enabled, secure)), + Obx(() => _LabeledTextField(context, 'Relay Server', + relayController, relayErrMsg.value, enabled, secure)), + Obx(() => _LabeledTextField(context, 'API Server', apiController, + apiErrMsg.value, enabled, secure)), + _LabeledTextField( + context, 'Key', keyController, "", enabled, secure), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [_Button('Apply', submit, enabled: enabled)], + ).marginOnly(top: 15), + ], + ) + ]); + }); + } } class _Account extends StatefulWidget { @@ -955,63 +1102,37 @@ class _AboutState extends State<_About> { //#region components // ignore: non_constant_identifier_names -Widget _Card({required String title, required List children}) { +Widget _Card( + {required String title, + required List children, + List? title_suffix}) { return Row( children: [ - SizedBox( - width: _kCardFixedWidth, - child: Card( - child: Column( - children: [ - Row( - children: [ - Text( - translate(title), - textAlign: TextAlign.start, - style: const TextStyle( - fontSize: _kTitleFontSize, - ), - ), - const Spacer(), - ], - ).marginOnly(left: _kContentHMargin, top: 10, bottom: 10), - ...children - .map((e) => e.marginOnly(top: 4, right: _kContentHMargin)), - ], - ).marginOnly(bottom: 10), - ).marginOnly(left: _kCardLeftMargin, top: 15), - ), - ], - ); -} - -Widget _CardRow({required String title, required List children}) { - return Row( - children: [ - SizedBox( - width: _kCardFixedWidth, - child: Card( - child: Column( - children: [ - Row( - children: [ - Text( - translate(title), - textAlign: TextAlign.start, - style: const TextStyle( - fontSize: _kTitleFontSize, - ), - ), - const Spacer(), - ], - ).marginOnly(left: _kContentHMargin, top: 10, bottom: 10), - Row(children: [ + Flexible( + child: SizedBox( + width: _kCardFixedWidth, + child: Card( + child: Column( + children: [ + Row( + children: [ + Expanded( + child: Text( + translate(title), + textAlign: TextAlign.start, + style: const TextStyle( + fontSize: _kTitleFontSize, + ), + )), + ...?title_suffix + ], + ).marginOnly(left: _kContentHMargin, top: 10, bottom: 10), ...children .map((e) => e.marginOnly(top: 4, right: _kContentHMargin)), - ]), - ], - ).marginOnly(bottom: 10), - ).marginOnly(left: _kCardLeftMargin, top: 15), + ], + ).marginOnly(bottom: 10), + ).marginOnly(left: _kCardLeftMargin, top: 15), + ), ), ], ); @@ -1085,6 +1206,7 @@ Widget _Radio(BuildContext context, required T groupValue, required String label, required Function(T value) onChanged, + bool autoNewLine = true, bool enabled = true}) { var onChange = enabled ? (T? value) { @@ -1099,8 +1221,7 @@ Widget _Radio(BuildContext context, Radio(value: value, groupValue: groupValue, onChanged: onChange), Expanded( child: Text(translate(label), - maxLines: 1, - overflow: TextOverflow.ellipsis, + overflow: autoNewLine ? null : TextOverflow.ellipsis, style: TextStyle( fontSize: _kContentFontSize, color: _disabledTextColor(context, enabled))) @@ -1116,12 +1237,11 @@ Widget _Radio(BuildContext context, Widget _Button(String label, Function() onPressed, {bool enabled = true, String? tip}) { var button = ElevatedButton( - onPressed: enabled ? onPressed : null, - child: Container( - child: Text( - translate(label), - ).marginSymmetric(horizontal: 15), - )); + onPressed: enabled ? onPressed : null, + child: Text( + translate(label), + ).marginSymmetric(horizontal: 15), + ); StatefulWidget child; if (tip == null) { child = button; @@ -1138,12 +1258,11 @@ Widget _SubButton(String label, Function() onPressed, [bool enabled = true]) { return Row( children: [ ElevatedButton( - onPressed: enabled ? onPressed : null, - child: Container( - child: Text( - translate(label), - ).marginSymmetric(horizontal: 15), - )), + onPressed: enabled ? onPressed : null, + child: Text( + translate(label), + ).marginSymmetric(horizontal: 15), + ), ], ).marginOnly(left: _kContentHSubMargin); } @@ -1215,34 +1334,72 @@ Widget _lock( offstage: !locked, child: Row( children: [ - SizedBox( - width: _kCardFixedWidth, - child: Card( - child: ElevatedButton( - child: SizedBox( - height: 25, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Icon( - Icons.security_sharp, - size: 20, - ), - Text(translate(label)).marginOnly(left: 5), - ]).marginSymmetric(vertical: 2)), - onPressed: () async { - bool checked = await bind.mainCheckSuperUserPermission(); - if (checked) { - onUnlock(); - } - }, - ).marginSymmetric(horizontal: 2, vertical: 4), - ).marginOnly(left: _kCardLeftMargin), - ).marginOnly(top: 10), + Flexible( + child: SizedBox( + width: _kCardFixedWidth, + child: Card( + child: ElevatedButton( + child: SizedBox( + height: 25, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Icon( + Icons.security_sharp, + size: 20, + ), + Text(translate(label)).marginOnly(left: 5), + ]).marginSymmetric(vertical: 2)), + onPressed: () async { + bool checked = await bind.mainCheckSuperUserPermission(); + if (checked) { + onUnlock(); + } + }, + ).marginSymmetric(horizontal: 2, vertical: 4), + ).marginOnly(left: _kCardLeftMargin), + ).marginOnly(top: 10), + ), ], )); } +_LabeledTextField( + BuildContext context, + String lable, + TextEditingController controller, + String errorText, + bool enabled, + bool secure) { + return Row( + children: [ + Spacer(flex: 1), + Expanded( + flex: 4, + child: Text( + '${translate(lable)}:', + textAlign: TextAlign.right, + style: TextStyle(color: _disabledTextColor(context, enabled)), + ), + ), + Spacer(flex: 1), + Expanded( + flex: 10, + child: TextField( + controller: controller, + enabled: enabled, + obscureText: secure, + decoration: InputDecoration( + errorText: errorText.isNotEmpty ? errorText : null), + style: TextStyle( + color: _disabledTextColor(context, enabled), + )), + ), + Spacer(flex: 1), + ], + ); +} + // ignore: must_be_immutable class _ComboBox extends StatelessWidget { late final List keys; @@ -1312,315 +1469,6 @@ class _ComboBox extends StatelessWidget { //#region dialogs -void changeServer() async { - Map oldOptions = jsonDecode(await bind.mainGetOptions()); - String idServer = oldOptions['custom-rendezvous-server'] ?? ""; - var idServerMsg = ""; - String relayServer = oldOptions['relay-server'] ?? ""; - var relayServerMsg = ""; - String apiServer = oldOptions['api-server'] ?? ""; - var apiServerMsg = ""; - var key = oldOptions['key'] ?? ""; - var idController = TextEditingController(text: idServer); - var relayController = TextEditingController(text: relayServer); - var apiController = TextEditingController(text: apiServer); - var keyController = TextEditingController(text: key); - - var isInProgress = false; - - gFFI.dialogManager.show((setState, close) { - submit() async { - setState(() { - idServerMsg = ""; - relayServerMsg = ""; - apiServerMsg = ""; - isInProgress = true; - }); - cancel() { - setState(() { - isInProgress = false; - }); - } - - idServer = idController.text.trim(); - relayServer = relayController.text.trim(); - apiServer = apiController.text.trim().toLowerCase(); - key = keyController.text.trim(); - - if (idServer.isNotEmpty) { - idServerMsg = - translate(await bind.mainTestIfValidServer(server: idServer)); - if (idServerMsg.isEmpty) { - oldOptions['custom-rendezvous-server'] = idServer; - } else { - cancel(); - return; - } - } else { - oldOptions['custom-rendezvous-server'] = ""; - } - - if (relayServer.isNotEmpty) { - relayServerMsg = - translate(await bind.mainTestIfValidServer(server: relayServer)); - if (relayServerMsg.isEmpty) { - oldOptions['relay-server'] = relayServer; - } else { - cancel(); - return; - } - } else { - oldOptions['relay-server'] = ""; - } - - if (apiServer.isNotEmpty) { - if (apiServer.startsWith('http://') || - apiServer.startsWith("https://")) { - oldOptions['api-server'] = apiServer; - return; - } else { - apiServerMsg = translate("invalid_http"); - cancel(); - return; - } - } else { - oldOptions['api-server'] = ""; - } - // ok - oldOptions['key'] = key; - await bind.mainSetOptions(json: jsonEncode(oldOptions)); - close(); - } - - return CustomAlertDialog( - title: Text(translate("ID/Relay Server")), - content: ConstrainedBox( - constraints: const BoxConstraints(minWidth: 500), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 8.0, - ), - Row( - children: [ - ConstrainedBox( - constraints: const BoxConstraints(minWidth: 100), - child: Text("${translate('ID Server')}:") - .marginOnly(bottom: 16.0)), - const SizedBox( - width: 24.0, - ), - Expanded( - child: TextField( - decoration: InputDecoration( - border: const OutlineInputBorder(), - errorText: idServerMsg.isNotEmpty ? idServerMsg : null), - controller: idController, - focusNode: FocusNode()..requestFocus(), - ), - ), - ], - ), - const SizedBox( - height: 8.0, - ), - Row( - children: [ - ConstrainedBox( - constraints: const BoxConstraints(minWidth: 100), - child: Text("${translate('Relay Server')}:") - .marginOnly(bottom: 16.0)), - const SizedBox( - width: 24.0, - ), - Expanded( - child: TextField( - decoration: InputDecoration( - border: const OutlineInputBorder(), - errorText: - relayServerMsg.isNotEmpty ? relayServerMsg : null), - controller: relayController, - ), - ), - ], - ), - const SizedBox( - height: 8.0, - ), - Row( - children: [ - ConstrainedBox( - constraints: const BoxConstraints(minWidth: 100), - child: Text("${translate('API Server')}:") - .marginOnly(bottom: 16.0)), - const SizedBox( - width: 24.0, - ), - Expanded( - child: TextField( - decoration: InputDecoration( - border: const OutlineInputBorder(), - errorText: - apiServerMsg.isNotEmpty ? apiServerMsg : null), - controller: apiController, - ), - ), - ], - ), - const SizedBox( - height: 8.0, - ), - Row( - children: [ - ConstrainedBox( - constraints: const BoxConstraints(minWidth: 100), - child: - Text("${translate('Key')}:").marginOnly(bottom: 16.0)), - const SizedBox( - width: 24.0, - ), - Expanded( - child: TextField( - decoration: const InputDecoration( - border: OutlineInputBorder(), - ), - controller: keyController, - ), - ), - ], - ), - const SizedBox( - height: 4.0, - ), - Offstage( - offstage: !isInProgress, child: const LinearProgressIndicator()) - ], - ), - ), - actions: [ - TextButton(onPressed: close, child: Text(translate("Cancel"))), - TextButton(onPressed: submit, child: Text(translate("OK"))), - ], - onSubmit: submit, - onCancel: close, - ); - }); -} - -void importServer() async { - Future importServerShow(String content) async { - gFFI.dialogManager.show((setState, close) { - return CustomAlertDialog( - title: Text(content), - content: ConstrainedBox( - constraints: const BoxConstraints(minWidth: 500), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 4.0, - ), - ], - ), - ), - actions: [ - TextButton(onPressed: close, child: Text(translate("OK"))), - ], - onCancel: close, - ); - }); - } - - Future submit( - String idServer, String relayServer, String apiServer, String key) async { - Map oldOptions = jsonDecode(await bind.mainGetOptions()); - var idServerMsg = ""; - var relayServerMsg = ""; - if (idServer.isNotEmpty) { - idServerMsg = - translate(await bind.mainTestIfValidServer(server: idServer)); - if (idServerMsg.isEmpty) { - oldOptions['custom-rendezvous-server'] = idServer; - } else { - debugPrint('ID Server invalid return'); - return false; - } - } else { - oldOptions['custom-rendezvous-server'] = ""; - } - - if (relayServer.isNotEmpty) { - relayServerMsg = - translate(await bind.mainTestIfValidServer(server: relayServer)); - if (relayServerMsg.isEmpty) { - oldOptions['relay-server'] = relayServer; - } else { - debugPrint('Relay Server invalid return'); - return false; - } - } else { - oldOptions['relay-server'] = ""; - } - - if (apiServer.isNotEmpty) { - if (apiServer.startsWith('http://') || apiServer.startsWith("https://")) { - oldOptions['api-server'] = apiServer; - return false; - } else { - debugPrint('invalid_http'); - return false; - } - } else { - oldOptions['api-server'] = ""; - } - // ok - oldOptions['key'] = key; - await bind.mainSetOptions(json: jsonEncode(oldOptions)); - debugPrint("set ID/Realy Server Ok"); - return true; - } - - Clipboard.getData(Clipboard.kTextPlain).then((value) { - TextEditingController mytext = TextEditingController(); - String? aNullableString = ""; - aNullableString = value?.text; - mytext.text = aNullableString.toString(); - if (mytext.text.isNotEmpty) { - debugPrint('Clipboard is not empty'); - try { - Map config = jsonDecode(mytext.text); - if (config.containsKey('IdServer') && - config.containsKey('RelayServer')) { - debugPrint('IdServer: ${config['IdServer']}'); - debugPrint('RelayServer: ${config['RelayServer']}'); - debugPrint('ApiServer: ${config['ApiServer']}'); - debugPrint('Key: ${config['Key']}'); - Future success = submit(config['IdServer'], - config['RelayServer'], config['ApiServer'], config['Key']); - success.then((value) { - if (value) { - importServerShow( - translate('Import server configuration successfully')); - } else { - importServerShow(translate('Invalid server configuration')); - } - }); - } else { - debugPrint('invalid config info'); - importServerShow(translate("Invalid server configuration")); - } - } catch (e) { - debugPrint('invalid config info'); - importServerShow(translate("Invalid server configuration")); - } - } else { - debugPrint('Clipboard is empty'); - importServerShow(translate("Clipboard is empty")); - } - }); -} - void changeSocks5Proxy() async { var socks = await bind.mainGetSocks(); diff --git a/src/lang/cn.rs b/src/lang/cn.rs index 32e30f81c..ca69ef4e4 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Enable TCP Tunneling", "允许建立TCP隧道"), ("IP Whitelisting", "IP白名单"), ("ID/Relay Server", "ID/中继服务器"), - ("Import Server Conf", "导入服务器配置"), + ("Import Server Config", "导入服务器配置"), + ("Export Server Config", "导出服务器配置"), ("Import server configuration successfully", "导入服务器配置信息成功"), + ("Export server configuration successfully", "导出服务器配置信息成功"), ("Invalid server configuration", "无效服务器配置,请修改后重新拷贝配置信息到剪贴板后点击此按钮"), ("Clipboard is empty", "拷贝配置信息到剪贴板后点击此按钮,可以自动导入配置"), ("Stop service", "停止服务"), diff --git a/src/lang/cs.rs b/src/lang/cs.rs index 6610c312b..84a5c590e 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Enable TCP Tunneling", "Povolit TCP tunelování"), ("IP Whitelisting", "Povolování pouze z daných IP adres)"), ("ID/Relay Server", "Identifikátor / předávací (relay) server"), - ("Import Server Conf", "Importovat konfiguraci serveru"), + ("Import Server Config", "Importovat konfiguraci serveru"), + ("Export Server Config", ""), ("Import server configuration successfully", "Konfigurace serveru úspěšně importována"), + ("Export server configuration successfully", ""), ("Invalid server configuration", "Neplatná konfigurace serveru"), ("Clipboard is empty", "Schránka je prázdná"), ("Stop service", "Zastavit službu"), diff --git a/src/lang/da.rs b/src/lang/da.rs index 3bf05a3d6..1210c2dba 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Enable TCP Tunneling", "Slå TCP-tunneling til"), ("IP Whitelisting", "IP-udgivelsesliste"), ("ID/Relay Server", "ID/forbindelsesserver"), - ("Import Server Conf", "Importér serverkonfiguration"), + ("Import Server Config", "Importér serverkonfiguration"), + ("Export Server Config", ""), ("Import server configuration successfully", "Importér serverkonfigurationen"), + ("Export server configuration successfully", ""), ("Invalid server configuration", "Ugyldig serverkonfiguration"), ("Clipboard is empty", "Udklipsholderen er tom"), ("Stop service", "Sluk for forbindelsesserveren"), diff --git a/src/lang/de.rs b/src/lang/de.rs index 095206f8e..95d0c3e5b 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Enable TCP Tunneling", "TCP-Tunnel aktivieren"), ("IP Whitelisting", "IP-Whitelist"), ("ID/Relay Server", "ID/Vermittlungsserver"), - ("Import Server Conf", "Serverkonfiguration importieren"), + ("Import Server Config", "Serverkonfiguration importieren"), + ("Export Server Config", ""), ("Import server configuration successfully", "Serverkonfiguration erfolgreich importiert"), + ("Export server configuration successfully", ""), ("Invalid server configuration", "Ungültige Serverkonfiguration"), ("Clipboard is empty", "Zwischenablage ist leer"), ("Stop service", "Vermittlungsdienst deaktivieren"), diff --git a/src/lang/eo.rs b/src/lang/eo.rs index 1b2a391d9..57955b9b8 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Enable TCP Tunneling", "Ebligi tunelado TCP"), ("IP Whitelisting", "Listo de IP akceptataj"), ("ID/Relay Server", "Identigila/Relajsa servilo"), - ("Import Server Conf", "Enporti servilan agordon"), + ("Import Server Config", "Enporti servilan agordon"), + ("Export Server Config", ""), ("Import server configuration successfully", "Importi servilan agordon sukcese"), + ("Export server configuration successfully", ""), ("Invalid server configuration", "Nevalida servila agordo"), ("Clipboard is empty", "La poŝo estas malplena"), ("Stop service", "Haltu servon"), diff --git a/src/lang/es.rs b/src/lang/es.rs index ef90bb711..39e904eda 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Enable TCP Tunneling", "Habilitar tunel TCP"), ("IP Whitelisting", "Lista blanca de IP"), ("ID/Relay Server", "Servidor ID/Relay"), - ("Import Server Conf", "Importar configuración de servidor"), + ("Import Server Config", "Importar configuración de servidor"), + ("Export Server Config", ""), ("Import server configuration successfully", "Configuración de servidor importada con éxito"), + ("Export server configuration successfully", ""), ("Invalid server configuration", "Configuración de servidor inválida"), ("Clipboard is empty", "El portapapeles está vacío"), ("Stop service", "Parar servicio"), diff --git a/src/lang/fr.rs b/src/lang/fr.rs index 8b6420823..8e75eec3a 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Enable TCP Tunneling", "Activer le tunneling TCP"), ("IP Whitelisting", "Liste blanche IP"), ("ID/Relay Server", "ID/Serveur Relais"), - ("Import Server Conf", "Importer la configuration du serveur"), + ("Import Server Config", "Importer la configuration du serveur"), + ("Export Server Config", ""), ("Import server configuration successfully", "Configuration du serveur importée avec succès"), + ("Export server configuration successfully", ""), ("Invalid server configuration", "Configuration du serveur non valide"), ("Clipboard is empty", "Presse-papier vide"), ("Stop service", "Arrêter le service"), diff --git a/src/lang/hu.rs b/src/lang/hu.rs index bbc0594a5..e26cdeff7 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Enable TCP Tunneling", "TCP Tunneling bekapcsolása"), ("IP Whitelisting", "IP Fehérlista"), ("ID/Relay Server", "ID/Relay Szerver"), - ("Import Server Conf", "Szerver Konfiguráció Importálása"), + ("Import Server Config", "Szerver Konfiguráció Importálása"), + ("Export Server Config", ""), ("Import server configuration successfully", "Szerver konfiguráció sikeresen importálva"), + ("Export server configuration successfully", ""), ("Invalid server configuration", "Érvénytelen szerver konfiguráció"), ("Clipboard is empty", "A vágólap üres"), ("Stop service", "Szolgáltatás Kikapcsolása"), diff --git a/src/lang/id.rs b/src/lang/id.rs index fc1ab88c2..8486e9e64 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Enable TCP Tunneling", "Aktifkan TCP Tunneling"), ("IP Whitelisting", "Daftar Putih IP"), ("ID/Relay Server", "ID/Relay Server"), - ("Import Server Conf", "Impor Konfigurasi Server"), + ("Import Server Config", "Impor Konfigurasi Server"), + ("Export Server Config", ""), ("Import server configuration successfully", "Impor konfigurasi server berhasil"), + ("Export server configuration successfully", ""), ("Invalid server configuration", "Konfigurasi server tidak valid"), ("Clipboard is empty", "Papan klip kosong"), ("Stop service", "Hentikan Layanan"), diff --git a/src/lang/it.rs b/src/lang/it.rs index bf2c76fe8..57ba210c3 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Enable TCP Tunneling", "Abilita tunnel TCP"), ("IP Whitelisting", "IP autorizzati"), ("ID/Relay Server", "Server ID/Relay"), - ("Import Server Conf", "Importa configurazione Server"), + ("Import Server Config", "Importa configurazione Server"), + ("Export Server Config", ""), ("Import server configuration successfully", "Configurazione Server importata con successo"), + ("Export server configuration successfully", ""), ("Invalid server configuration", "Configurazione Server non valida"), ("Clipboard is empty", "Gli appunti sono vuoti"), ("Stop service", "Arresta servizio"), diff --git a/src/lang/ja.rs b/src/lang/ja.rs index 38e4c0c7d..207a874ec 100644 --- a/src/lang/ja.rs +++ b/src/lang/ja.rs @@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Enable TCP Tunneling", "TCPトンネリングを有効化"), ("IP Whitelisting", "IPホワイトリスト"), ("ID/Relay Server", "認証・中継サーバー"), - ("Import Server Conf", "サーバー設定をインポート"), + ("Import Server Config", "サーバー設定をインポート"), + ("Export Server Config", ""), ("Import server configuration successfully", "サーバー設定をインポートしました"), + ("Export server configuration successfully", ""), ("Invalid server configuration", "無効なサーバー設定です"), ("Clipboard is empty", "クリップボードは空です"), ("Stop service", "サービスを停止"), diff --git a/src/lang/ko.rs b/src/lang/ko.rs index 740465323..5ed580ff3 100644 --- a/src/lang/ko.rs +++ b/src/lang/ko.rs @@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Enable TCP Tunneling", "TCP 터널링 활성화"), ("IP Whitelisting", "IP 화이트리스트"), ("ID/Relay Server", "ID/Relay 서버"), - ("Import Server Conf", "서버 설정 가져오기"), + ("Import Server Config", "서버 설정 가져오기"), + ("Export Server Config", ""), ("Import server configuration successfully", "서버 설정 가져오기 성공"), + ("Export server configuration successfully", ""), ("Invalid server configuration", "잘못된 서버 설정"), ("Clipboard is empty", "클립보드가 비어있습니다"), ("Stop service", "서비스 중단"), diff --git a/src/lang/kz.rs b/src/lang/kz.rs index a4f25dbf8..ad7bdb476 100644 --- a/src/lang/kz.rs +++ b/src/lang/kz.rs @@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Enable TCP Tunneling", "TCP тунелдеуді қосу"), ("IP Whitelisting", "IP Ақ-тізімі"), ("ID/Relay Server", "ID/Relay сербері"), - ("Import Server Conf", "Серверді импорттау"), + ("Import Server Config", "Серверді импорттау"), + ("Export Server Config", ""), ("Import server configuration successfully", "Сервердің конфигурациясы сәтті импортталды"), + ("Export server configuration successfully", ""), ("Invalid server configuration", "Жарамсыз сервердің конфигурациясы"), ("Clipboard is empty", "Көшіру-тақта бос"), ("Stop service", "Сербесті тоқтату"), diff --git a/src/lang/pl.rs b/src/lang/pl.rs index e46796148..2a08479aa 100644 --- a/src/lang/pl.rs +++ b/src/lang/pl.rs @@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Enable TCP Tunneling", "Włącz tunelowanie TCP"), ("IP Whitelisting", "Biała lista IP"), ("ID/Relay Server", "Serwer ID/Pośredniczący"), - ("Import Server Conf", "Importuj konfigurację serwera"), + ("Import Server Config", "Importuj konfigurację serwera"), + ("Export Server Config", ""), ("Import server configuration successfully", "Importowanie konfiguracji serwera powiodło się"), + ("Export server configuration successfully", ""), ("Invalid server configuration", "Nieprawidłowa konfiguracja serwera"), ("Clipboard is empty", "Schowek jest pusty"), ("Stop service", "Zatrzymaj usługę"), diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs index 69b61d622..fc40cbfb8 100644 --- a/src/lang/pt_PT.rs +++ b/src/lang/pt_PT.rs @@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Enable TCP Tunneling", "Activar Túnel TCP"), ("IP Whitelisting", "Whitelist de IP"), ("ID/Relay Server", "Servidor ID/Relay"), - ("Import Server Conf", "Importar Configuração do Servidor"), + ("Import Server Config", "Importar Configuração do Servidor"), + ("Export Server Config", ""), ("Import server configuration successfully", "Configuração do servidor importada com sucesso"), + ("Export server configuration successfully", ""), ("Invalid server configuration", "Configuração do servidor inválida"), ("Clipboard is empty", "A área de transferência está vazia"), ("Stop service", "Parar serviço"), diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index e93cbef33..adeee81a4 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Enable TCP Tunneling", "Habilitar Tunelamento TCP"), ("IP Whitelisting", "Whitelist de IP"), ("ID/Relay Server", "Servidor ID/Relay"), - ("Import Server Conf", "Importar Configuração do Servidor"), + ("Import Server Config", "Importar Configuração do Servidor"), + ("Export Server Config", ""), ("Import server configuration successfully", "Configuração do servidor importada com sucesso"), + ("Export server configuration successfully", ""), ("Invalid server configuration", "Configuração do servidor inválida"), ("Clipboard is empty", "A área de transferência está vazia"), ("Stop service", "Parar serviço"), diff --git a/src/lang/ru.rs b/src/lang/ru.rs index eccc28602..3ddc40d53 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Enable TCP Tunneling", "Включить туннелирование TCP"), ("IP Whitelisting", "Список разрешенных IP-адресов"), ("ID/Relay Server", "ID/Сервер ретрансляции"), - ("Import Server Conf", "Импортировать конфигурацию сервера"), + ("Import Server Config", "Импортировать конфигурацию сервера"), + ("Export Server Config", ""), ("Import server configuration successfully", "Конфигурация сервера успешно импортирована"), + ("Export server configuration successfully", ""), ("Invalid server configuration", "Недопустимая конфигурация сервера"), ("Clipboard is empty", "Буфер обмена пуст"), ("Stop service", "Остановить службу"), diff --git a/src/lang/sk.rs b/src/lang/sk.rs index 20e096f0e..107f38bf8 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Enable TCP Tunneling", "Povoliť TCP tunelovanie"), ("IP Whitelisting", "Zoznam povolených IP adries"), ("ID/Relay Server", "ID/Prepojovací server"), - ("Import Server Conf", "Importovať konfiguráciu servera"), + ("Import Server Config", "Importovať konfiguráciu servera"), + ("Export Server Config", ""), ("Import server configuration successfully", "Konfigurácia servera bola úspešne importovaná"), + ("Export server configuration successfully", ""), ("Invalid server configuration", "Neplatná konfigurácia servera"), ("Clipboard is empty", "Schránka je prázdna"), ("Stop service", "Zastaviť službu"), diff --git a/src/lang/template.rs b/src/lang/template.rs index 87dcc3a48..a08eec33d 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Enable TCP Tunneling", ""), ("IP Whitelisting", ""), ("ID/Relay Server", ""), - ("Import Server Conf", ""), + ("Import Server Config", ""), + ("Export Server Config", ""), ("Import server configuration successfully", ""), + ("Export server configuration successfully", ""), ("Invalid server configuration", ""), ("Clipboard is empty", ""), ("Stop service", ""), diff --git a/src/lang/tr.rs b/src/lang/tr.rs index f8d8b5fff..99fad87bc 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Enable TCP Tunneling", "TCP Tüneline izin ver"), ("IP Whitelisting", "İzinli IP listesi"), ("ID/Relay Server", "ID/Relay Sunucusu"), - ("Import Server Conf", "Sunucu ayarlarını içe aktar"), + ("Import Server Config", "Sunucu ayarlarını içe aktar"), + ("Export Server Config", ""), ("Import server configuration successfully", "Sunucu ayarları başarıyla içe aktarıldı"), + ("Export server configuration successfully", ""), ("Invalid server configuration", "Geçersiz sunucu ayarı"), ("Clipboard is empty", "Kopyalanan geçici veri boş"), ("Stop service", "Servisi Durdur"), diff --git a/src/lang/tw.rs b/src/lang/tw.rs index 0c085775e..d20888aeb 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -29,8 +29,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Enable TCP Tunneling", "啟用 TCP 通道"), ("IP Whitelisting", "IP 白名單"), ("ID/Relay Server", "ID/轉送伺服器"), - ("Import Server Conf", "匯入伺服器設定"), + ("Import Server Config", "匯入伺服器設定"), + ("Export Server Config", "導出服務器配置"), ("Import server configuration successfully", "匯入伺服器設定成功"), + ("Export server configuration successfully", ""), + ("Export server configuration successfully", "導出服務器配置信息成功"), ("Invalid server configuration", "無效的伺服器設定"), ("Clipboard is empty", "剪貼簿是空的"), ("Stop service", "停止服務"), diff --git a/src/lang/ua.rs b/src/lang/ua.rs index 8d3451db0..f6c389533 100644 --- a/src/lang/ua.rs +++ b/src/lang/ua.rs @@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Enable TCP Tunneling", "Увімкнути тунелювання TCP"), ("IP Whitelisting", "Список дозволених IP-адрес"), ("ID/Relay Server", "ID/Сервер ретрансляції"), - ("Import Server Conf", "Імпортувати конфігурацію сервера"), + ("Import Server Config", "Імпортувати конфігурацію сервера"), + ("Export Server Config", ""), ("Import server configuration successfully", "Конфігурацію сервера успішно імпортовано"), + ("Export server configuration successfully", ""), ("Invalid server configuration", "Недійсна конфігурація сервера"), ("Clipboard is empty", "Буфер обміну порожній"), ("Stop service", "Зупинити службу"), diff --git a/src/lang/vn.rs b/src/lang/vn.rs index 81428a8ec..f4823dbfd 100644 --- a/src/lang/vn.rs +++ b/src/lang/vn.rs @@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Enable TCP Tunneling", "Cho phép TCP Tunneling"), ("IP Whitelisting", "Cho phép IP"), ("ID/Relay Server", "Máy chủ ID/Relay"), - ("Import Server Conf", "Nhập cấu hình máy chủ"), + ("Import Server Config", "Nhập cấu hình máy chủ"), + ("Export Server Config", ""), ("Import server configuration successfully", "Nhập cấu hình máy chủ thành công"), + ("Export server configuration successfully", ""), ("Invalid server configuration", "Cấu hình máy chủ không hợp lệ"), ("Clipboard is empty", "Khay nhớ tạm trống"), ("Stop service", "Dừng dịch vụ"), From 41893e2ac2a81e10d29fe704a277de74826a4367 Mon Sep 17 00:00:00 2001 From: 21pages Date: Sat, 22 Oct 2022 16:56:21 +0800 Subject: [PATCH 2/4] replace cmd.exe with rustdek.exe when check uac Signed-off-by: 21pages --- src/platform/windows.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/platform/windows.rs b/src/platform/windows.rs index 190a49a16..278d79d92 100644 --- a/src/platform/windows.rs +++ b/src/platform/windows.rs @@ -1478,7 +1478,13 @@ pub fn run_uac(exe: &str, arg: &str) -> ResultType { } pub fn check_super_user_permission() -> ResultType { - run_uac("cmd", "/c /q") + run_uac( + std::env::current_exe()? + .to_string_lossy() + .to_string() + .as_str(), + "--version", + ) } pub fn elevate(arg: &str) -> ResultType { From d48a94e5309cda5124befa3bee5dfd52383454ea Mon Sep 17 00:00:00 2001 From: 21pages Date: Sat, 22 Oct 2022 21:55:36 +0800 Subject: [PATCH 3/4] forceUpdate when unminisized on windows Signed-off-by: 21pages --- .../lib/desktop/pages/connection_page.dart | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 30b685347..506a03b7a 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:convert'; +import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_hbb/common/widgets/address_book.dart'; @@ -9,6 +10,7 @@ import 'package:flutter_hbb/consts.dart'; import 'package:flutter_hbb/desktop/widgets/scroll_wrapper.dart'; import 'package:get/get.dart'; import 'package:url_launcher/url_launcher_string.dart'; +import 'package:window_manager/window_manager.dart'; import '../../common.dart'; import '../../common/formatter/id_formatter.dart'; @@ -27,7 +29,7 @@ class ConnectionPage extends StatefulWidget { /// State for the connection page. class _ConnectionPageState extends State - with SingleTickerProviderStateMixin { + with SingleTickerProviderStateMixin, WindowListener { /// Controller for the id input bar. final _idController = IDTextEditingController(); @@ -43,6 +45,8 @@ class _ConnectionPageState extends State var svcStatusCode = 0.obs; var svcIsUsingPublicServer = true.obs; + bool isWindowMinisized = false; + @override void initState() { super.initState(); @@ -63,6 +67,7 @@ class _ConnectionPageState extends State _idInputFocused.value = _idFocusNode.hasFocus; }); Get.put(svcStopped, tag: 'service-stop'); + windowManager.addListener(this); } @override @@ -70,9 +75,24 @@ class _ConnectionPageState extends State _idController.dispose(); _updateTimer?.cancel(); Get.delete(tag: 'service-stop'); + windowManager.removeListener(this); super.dispose(); } + @override + void onWindowEvent(String eventName) { + super.onWindowEvent(eventName); + if (eventName == 'minimize') { + isWindowMinisized = true; + } else if (eventName == 'maximize' || eventName == 'restore') { + if (isWindowMinisized && Platform.isWindows) { + // windows can't update when minisized. + Get.forceAppUpdate(); + } + isWindowMinisized = false; + } + } + @override Widget build(BuildContext context) { return Column( From 894fe69285725e02d1cb2536c3a4302404acb16f Mon Sep 17 00:00:00 2001 From: 21pages Date: Sun, 23 Oct 2022 19:52:30 +0800 Subject: [PATCH 4/4] fix flutter upgrade Signed-off-by: 21pages --- flutter/lib/desktop/pages/install_page.dart | 2 +- flutter/windows/runner/main.cpp | 21 +++++----- src/platform/windows.rs | 44 ++++++++++++--------- 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/flutter/lib/desktop/pages/install_page.dart b/flutter/lib/desktop/pages/install_page.dart index 73ad8769d..e7bb28813 100644 --- a/flutter/lib/desktop/pages/install_page.dart +++ b/flutter/lib/desktop/pages/install_page.dart @@ -181,7 +181,7 @@ class _InstallPageState extends State with WindowListener { void install() { btnEnabled.value = false; showProgress.value = true; - String args = '--flutter'; + String args = ''; if (startmenu.value) args += ' startmenu'; if (desktopicon.value) args += ' desktopicon'; bind.installInstallMe(options: args, path: controller.text); diff --git a/flutter/windows/runner/main.cpp b/flutter/windows/runner/main.cpp index 66194ed42..fed399c9a 100644 --- a/flutter/windows/runner/main.cpp +++ b/flutter/windows/runner/main.cpp @@ -16,15 +16,6 @@ typedef void (*FUNC_RUSTDESK_FREE_ARGS)( char**, int); int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, _In_ wchar_t *command_line, _In_ int show_command) { - // uni links dispatch - HWND hwnd = ::FindWindow(L"FLUTTER_RUNNER_WIN32_WINDOW", L"rustdesk"); - if (hwnd != NULL) { - DispatchToUniLinksDesktop(hwnd); - - ::ShowWindow(hwnd, SW_NORMAL); - ::SetForegroundWindow(hwnd); - return EXIT_FAILURE; - } HINSTANCE hInstance = LoadLibraryA("librustdesk.dll"); if (!hInstance) { @@ -56,6 +47,16 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, std::vector rust_args(c_args, c_args + args_len); free_c_args(c_args, args_len); + // uni links dispatch + HWND hwnd = ::FindWindow(L"FLUTTER_RUNNER_WIN32_WINDOW", L"rustdesk"); + if (hwnd != NULL) { + DispatchToUniLinksDesktop(hwnd); + + ::ShowWindow(hwnd, SW_NORMAL); + ::SetForegroundWindow(hwnd); + return EXIT_FAILURE; + } + // Attach to console when present (e.g., 'flutter run') or create a // new console when running with a debugger. if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) @@ -78,7 +79,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, FlutterWindow window(project); Win32Window::Point origin(10, 10); Win32Window::Size size(800, 600); - if (!window.CreateAndShow(L"rustdesk", origin, size)) + if (!window.CreateAndShow(L"RustDesk", origin, size)) { return EXIT_FAILURE; } diff --git a/src/platform/windows.rs b/src/platform/windows.rs index 278d79d92..53fb60bd8 100644 --- a/src/platform/windows.rs +++ b/src/platform/windows.rs @@ -878,6 +878,25 @@ fn get_install_info_with_subkey(subkey: String) -> (String, String, String, Stri (subkey, path, start_menu, exe) } +pub fn copy_exe_cmd(src_exe: &str, _exe: &str, _path: &str) -> String { + #[cfg(feature = "flutter")] + return format!( + "XCOPY \"{}\" \"{}\" /Y /E /H /C /I /K /R /Z", + PathBuf::from(src_exe) + .parent() + .unwrap() + .to_string_lossy() + .to_string(), + _path + ); + #[cfg(not(feature = "flutter"))] + return format!( + "copy /Y \"{src_exe}\" \"{exe}\"", + src_exe = src_exe, + exe = _exe + ); +} + pub fn update_me() -> ResultType<()> { let (_, path, _, exe) = get_install_info(); let src_exe = std::env::current_exe()?.to_str().unwrap_or("").to_owned(); @@ -887,13 +906,13 @@ pub fn update_me() -> ResultType<()> { sc stop {app_name} taskkill /F /IM {broker_exe} taskkill /F /IM {app_name}.exe - copy /Y \"{src_exe}\" \"{exe}\" + {copy_exe} \"{src_exe}\" --extract \"{path}\" sc start {app_name} {lic} ", src_exe = src_exe, - exe = exe, + copy_exe = copy_exe_cmd(&src_exe, &exe, &path), broker_exe = crate::ui::win_privacy::INJECTED_PROCESS_EXE, path = path, app_name = crate::get_app_name(), @@ -1038,18 +1057,6 @@ copy /Y \"{tmp_path}\\Uninstall {app_name}.lnk\" \"{start_menu}\\\" app_name = crate::get_app_name(), ); } - let mut flutter_copy = Default::default(); - if options.contains("--flutter") { - flutter_copy = format!( - "XCOPY \"{}\" \"{}\" /Y /E /H /C /I /K /R /Z", - std::env::current_exe()? - .parent() - .unwrap() - .to_string_lossy() - .to_string(), - path - ); - } let meta = std::fs::symlink_metadata(std::env::current_exe()?)?; let size = meta.len() / 1024; @@ -1072,13 +1079,14 @@ if exist \"{tmp_path}\\{app_name} Tray.lnk\" del /f /q \"{tmp_path}\\{app_name} tmp_path = tmp_path, app_name = crate::get_app_name(), ); + let src_exe = std::env::current_exe()?.to_str().unwrap_or("").to_string(); + let cmds = format!( " {uninstall_str} chcp 65001 md \"{path}\" -{flutter_copy} -copy /Y \"{src_exe}\" \"{exe}\" +{copy_exe} copy /Y \"{ORIGIN_PROCESS_EXE}\" \"{path}\\{broker_exe}\" \"{src_exe}\" --extract \"{path}\" reg add {subkey} /f @@ -1111,7 +1119,7 @@ sc delete {app_name} ", uninstall_str=uninstall_str, path=path, - src_exe=std::env::current_exe()?.to_str().unwrap_or(""), + src_exe=src_exe, exe=exe, ORIGIN_PROCESS_EXE = crate::ui::win_privacy::ORIGIN_PROCESS_EXE, broker_exe=crate::ui::win_privacy::INJECTED_PROCESS_EXE, @@ -1140,7 +1148,7 @@ sc delete {app_name} } else { &dels }, - flutter_copy = flutter_copy, + copy_exe = copy_exe_cmd(&src_exe, &exe, &path), ); run_cmds(cmds, debug, "install")?; std::thread::sleep(std::time::Duration::from_millis(2000));