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 8964191f..30b68534 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 23d83258..22247c03 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 32e30f81..ca69ef4e 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 6610c312..84a5c590 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 3bf05a3d..1210c2db 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 095206f8..95d0c3e5 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 1b2a391d..57955b9b 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 ef90bb71..39e904ed 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 8b642082..8e75eec3 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 bbc0594a..e26cdeff 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 fc1ab88c..8486e9e6 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 bf2c76fe..57ba210c 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 38e4c0c7..207a874e 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 74046532..5ed580ff 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 a4f25dbf..ad7bdb47 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 e4679614..2a08479a 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 69b61d62..fc40cbfb 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 e93cbef3..adeee81a 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 eccc2860..3ddc40d5 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 20e096f0..107f38bf 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 87dcc3a4..a08eec33 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 f8d8b5ff..99fad87b 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 0c085775..d20888ae 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 8d3451db..f6c38953 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 81428a8e..f4823dbf 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 190a49a1..278d79d9 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 30b68534..506a03b7 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 73ad8769..e7bb2881 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 66194ed4..fed399c9 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 278d79d9..53fb60bd 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));