Merge pull request #1788 from 21pages/fix-flutter-upgrade

Fix flutter upgrade
This commit is contained in:
RustDesk 2022-10-24 01:09:13 +08:00 committed by GitHub
commit a2cb295a11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 417 additions and 476 deletions

View File

@ -2,6 +2,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_hbb/common/widgets/address_book.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:flutter_hbb/desktop/widgets/scroll_wrapper.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:url_launcher/url_launcher_string.dart'; import 'package:url_launcher/url_launcher_string.dart';
import 'package:window_manager/window_manager.dart';
import '../../common.dart'; import '../../common.dart';
import '../../common/formatter/id_formatter.dart'; import '../../common/formatter/id_formatter.dart';
@ -27,7 +29,7 @@ class ConnectionPage extends StatefulWidget {
/// State for the connection page. /// State for the connection page.
class _ConnectionPageState extends State<ConnectionPage> class _ConnectionPageState extends State<ConnectionPage>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin, WindowListener {
/// Controller for the id input bar. /// Controller for the id input bar.
final _idController = IDTextEditingController(); final _idController = IDTextEditingController();
@ -43,6 +45,8 @@ class _ConnectionPageState extends State<ConnectionPage>
var svcStatusCode = 0.obs; var svcStatusCode = 0.obs;
var svcIsUsingPublicServer = true.obs; var svcIsUsingPublicServer = true.obs;
bool isWindowMinisized = false;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -63,6 +67,7 @@ class _ConnectionPageState extends State<ConnectionPage>
_idInputFocused.value = _idFocusNode.hasFocus; _idInputFocused.value = _idFocusNode.hasFocus;
}); });
Get.put<RxBool>(svcStopped, tag: 'service-stop'); Get.put<RxBool>(svcStopped, tag: 'service-stop');
windowManager.addListener(this);
} }
@override @override
@ -70,9 +75,24 @@ class _ConnectionPageState extends State<ConnectionPage>
_idController.dispose(); _idController.dispose();
_updateTimer?.cancel(); _updateTimer?.cancel();
Get.delete<RxBool>(tag: 'service-stop'); Get.delete<RxBool>(tag: 'service-stop');
windowManager.removeListener(this);
super.dispose(); 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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Column(
@ -282,23 +302,34 @@ class _ConnectionPageState extends State<ConnectionPage>
.marginOnly(left: em), .marginOnly(left: em),
), ),
// ready && public // ready && public
Offstage( Flexible(
offstage: !(!svcStopped.value && child: Offstage(
svcStatusCode.value == 1 && offstage: !(!svcStopped.value &&
svcIsUsingPublicServer.value), svcStatusCode.value == 1 &&
child: Row( svcIsUsingPublicServer.value),
crossAxisAlignment: CrossAxisAlignment.center, child: Row(
children: [ crossAxisAlignment: CrossAxisAlignment.center,
Text(', ', style: TextStyle(fontSize: em)), children: [
InkWell( Text(', ', style: TextStyle(fontSize: em)),
onTap: onUsePublicServerGuide, Flexible(
child: Text( child: InkWell(
translate('setup_server_tip'), onTap: onUsePublicServerGuide,
style: TextStyle( child: Row(
decoration: TextDecoration.underline, fontSize: em), children: [
), Flexible(
) child: Text(
], translate('setup_server_tip'),
style: TextStyle(
decoration: TextDecoration.underline,
fontSize: em),
),
),
],
),
),
)
],
),
), ),
) )
], ],

View File

@ -321,6 +321,7 @@ class _GeneralState extends State<_General> {
...devices.map((device) => _Radio<String>(context, ...devices.map((device) => _Radio<String>(context,
value: device, value: device,
groupValue: currentDevice, groupValue: currentDevice,
autoNewLine: false,
label: device, onChanged: (value) { label: device, onChanged: (value) {
setDevice(value); setDevice(value);
setState(() {}); setState(() {});
@ -812,11 +813,7 @@ class _NetworkState extends State<_Network> with AutomaticKeepAliveClientMixin {
AbsorbPointer( AbsorbPointer(
absorbing: locked, absorbing: locked,
child: Column(children: [ child: Column(children: [
_CardRow(title: 'Server', children: [ server(enabled),
_Button('ID/Relay Server', changeServer, enabled: enabled),
_Button('Import Server Conf', importServer,
enabled: enabled),
]),
_Card(title: 'Proxy', children: [ _Card(title: 'Proxy', children: [
_Button('Socks5 Proxy', changeSocks5Proxy, _Button('Socks5 Proxy', changeSocks5Proxy,
enabled: enabled), enabled: enabled),
@ -825,6 +822,156 @@ class _NetworkState extends State<_Network> with AutomaticKeepAliveClientMixin {
), ),
]).marginOnly(bottom: _kListViewBottomMargin)); ]).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<String, dynamic> 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<String, dynamic> 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<bool> 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<String, String> 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 { class _Account extends StatefulWidget {
@ -955,63 +1102,37 @@ class _AboutState extends State<_About> {
//#region components //#region components
// ignore: non_constant_identifier_names // ignore: non_constant_identifier_names
Widget _Card({required String title, required List<Widget> children}) { Widget _Card(
{required String title,
required List<Widget> children,
List<Widget>? title_suffix}) {
return Row( return Row(
children: [ children: [
SizedBox( Flexible(
width: _kCardFixedWidth, child: SizedBox(
child: Card( width: _kCardFixedWidth,
child: Column( child: Card(
children: [ child: Column(
Row( children: [
children: [ Row(
Text( children: [
translate(title), Expanded(
textAlign: TextAlign.start, child: Text(
style: const TextStyle( translate(title),
fontSize: _kTitleFontSize, textAlign: TextAlign.start,
), style: const TextStyle(
), fontSize: _kTitleFontSize,
const Spacer(), ),
], )),
).marginOnly(left: _kContentHMargin, top: 10, bottom: 10), ...?title_suffix
...children ],
.map((e) => e.marginOnly(top: 4, right: _kContentHMargin)), ).marginOnly(left: _kContentHMargin, top: 10, bottom: 10),
],
).marginOnly(bottom: 10),
).marginOnly(left: _kCardLeftMargin, top: 15),
),
],
);
}
Widget _CardRow({required String title, required List<Widget> 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: [
...children ...children
.map((e) => e.marginOnly(top: 4, right: _kContentHMargin)), .map((e) => e.marginOnly(top: 4, right: _kContentHMargin)),
]), ],
], ).marginOnly(bottom: 10),
).marginOnly(bottom: 10), ).marginOnly(left: _kCardLeftMargin, top: 15),
).marginOnly(left: _kCardLeftMargin, top: 15), ),
), ),
], ],
); );
@ -1085,6 +1206,7 @@ Widget _Radio<T>(BuildContext context,
required T groupValue, required T groupValue,
required String label, required String label,
required Function(T value) onChanged, required Function(T value) onChanged,
bool autoNewLine = true,
bool enabled = true}) { bool enabled = true}) {
var onChange = enabled var onChange = enabled
? (T? value) { ? (T? value) {
@ -1099,8 +1221,7 @@ Widget _Radio<T>(BuildContext context,
Radio<T>(value: value, groupValue: groupValue, onChanged: onChange), Radio<T>(value: value, groupValue: groupValue, onChanged: onChange),
Expanded( Expanded(
child: Text(translate(label), child: Text(translate(label),
maxLines: 1, overflow: autoNewLine ? null : TextOverflow.ellipsis,
overflow: TextOverflow.ellipsis,
style: TextStyle( style: TextStyle(
fontSize: _kContentFontSize, fontSize: _kContentFontSize,
color: _disabledTextColor(context, enabled))) color: _disabledTextColor(context, enabled)))
@ -1116,12 +1237,11 @@ Widget _Radio<T>(BuildContext context,
Widget _Button(String label, Function() onPressed, Widget _Button(String label, Function() onPressed,
{bool enabled = true, String? tip}) { {bool enabled = true, String? tip}) {
var button = ElevatedButton( var button = ElevatedButton(
onPressed: enabled ? onPressed : null, onPressed: enabled ? onPressed : null,
child: Container( child: Text(
child: Text( translate(label),
translate(label), ).marginSymmetric(horizontal: 15),
).marginSymmetric(horizontal: 15), );
));
StatefulWidget child; StatefulWidget child;
if (tip == null) { if (tip == null) {
child = button; child = button;
@ -1138,12 +1258,11 @@ Widget _SubButton(String label, Function() onPressed, [bool enabled = true]) {
return Row( return Row(
children: [ children: [
ElevatedButton( ElevatedButton(
onPressed: enabled ? onPressed : null, onPressed: enabled ? onPressed : null,
child: Container( child: Text(
child: Text( translate(label),
translate(label), ).marginSymmetric(horizontal: 15),
).marginSymmetric(horizontal: 15), ),
)),
], ],
).marginOnly(left: _kContentHSubMargin); ).marginOnly(left: _kContentHSubMargin);
} }
@ -1215,34 +1334,72 @@ Widget _lock(
offstage: !locked, offstage: !locked,
child: Row( child: Row(
children: [ children: [
SizedBox( Flexible(
width: _kCardFixedWidth, child: SizedBox(
child: Card( width: _kCardFixedWidth,
child: ElevatedButton( child: Card(
child: SizedBox( child: ElevatedButton(
height: 25, child: SizedBox(
child: Row( height: 25,
mainAxisAlignment: MainAxisAlignment.center, child: Row(
children: [ mainAxisAlignment: MainAxisAlignment.center,
const Icon( children: [
Icons.security_sharp, const Icon(
size: 20, Icons.security_sharp,
), size: 20,
Text(translate(label)).marginOnly(left: 5), ),
]).marginSymmetric(vertical: 2)), Text(translate(label)).marginOnly(left: 5),
onPressed: () async { ]).marginSymmetric(vertical: 2)),
bool checked = await bind.mainCheckSuperUserPermission(); onPressed: () async {
if (checked) { bool checked = await bind.mainCheckSuperUserPermission();
onUnlock(); if (checked) {
} onUnlock();
}, }
).marginSymmetric(horizontal: 2, vertical: 4), },
).marginOnly(left: _kCardLeftMargin), ).marginSymmetric(horizontal: 2, vertical: 4),
).marginOnly(top: 10), ).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 // ignore: must_be_immutable
class _ComboBox extends StatelessWidget { class _ComboBox extends StatelessWidget {
late final List<String> keys; late final List<String> keys;
@ -1312,315 +1469,6 @@ class _ComboBox extends StatelessWidget {
//#region dialogs //#region dialogs
void changeServer() async {
Map<String, dynamic> 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<void> 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<bool> submit(
String idServer, String relayServer, String apiServer, String key) async {
Map<String, dynamic> 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<String, dynamic> 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<bool> 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 { void changeSocks5Proxy() async {
var socks = await bind.mainGetSocks(); var socks = await bind.mainGetSocks();

View File

@ -181,7 +181,7 @@ class _InstallPageState extends State<InstallPage> with WindowListener {
void install() { void install() {
btnEnabled.value = false; btnEnabled.value = false;
showProgress.value = true; showProgress.value = true;
String args = '--flutter'; String args = '';
if (startmenu.value) args += ' startmenu'; if (startmenu.value) args += ' startmenu';
if (desktopicon.value) args += ' desktopicon'; if (desktopicon.value) args += ' desktopicon';
bind.installInstallMe(options: args, path: controller.text); bind.installInstallMe(options: args, path: controller.text);

View File

@ -16,15 +16,6 @@ typedef void (*FUNC_RUSTDESK_FREE_ARGS)( char**, int);
int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
_In_ wchar_t *command_line, _In_ int show_command) _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"); HINSTANCE hInstance = LoadLibraryA("librustdesk.dll");
if (!hInstance) if (!hInstance)
{ {
@ -56,6 +47,16 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
std::vector<std::string> rust_args(c_args, c_args + args_len); std::vector<std::string> rust_args(c_args, c_args + args_len);
free_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 // Attach to console when present (e.g., 'flutter run') or create a
// new console when running with a debugger. // new console when running with a debugger.
if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent())
@ -78,7 +79,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
FlutterWindow window(project); FlutterWindow window(project);
Win32Window::Point origin(10, 10); Win32Window::Point origin(10, 10);
Win32Window::Size size(800, 600); Win32Window::Size size(800, 600);
if (!window.CreateAndShow(L"rustdesk", origin, size)) if (!window.CreateAndShow(L"RustDesk", origin, size))
{ {
return EXIT_FAILURE; return EXIT_FAILURE;
} }

View File

@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable TCP Tunneling", "允许建立TCP隧道"), ("Enable TCP Tunneling", "允许建立TCP隧道"),
("IP Whitelisting", "IP白名单"), ("IP Whitelisting", "IP白名单"),
("ID/Relay Server", "ID/中继服务器"), ("ID/Relay Server", "ID/中继服务器"),
("Import Server Conf", "导入服务器配置"), ("Import Server Config", "导入服务器配置"),
("Export Server Config", "导出服务器配置"),
("Import server configuration successfully", "导入服务器配置信息成功"), ("Import server configuration successfully", "导入服务器配置信息成功"),
("Export server configuration successfully", "导出服务器配置信息成功"),
("Invalid server configuration", "无效服务器配置,请修改后重新拷贝配置信息到剪贴板后点击此按钮"), ("Invalid server configuration", "无效服务器配置,请修改后重新拷贝配置信息到剪贴板后点击此按钮"),
("Clipboard is empty", "拷贝配置信息到剪贴板后点击此按钮,可以自动导入配置"), ("Clipboard is empty", "拷贝配置信息到剪贴板后点击此按钮,可以自动导入配置"),
("Stop service", "停止服务"), ("Stop service", "停止服务"),

View File

@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable TCP Tunneling", "Povolit TCP tunelování"), ("Enable TCP Tunneling", "Povolit TCP tunelování"),
("IP Whitelisting", "Povolování pouze z daných IP adres)"), ("IP Whitelisting", "Povolování pouze z daných IP adres)"),
("ID/Relay Server", "Identifikátor / předávací (relay) server"), ("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"), ("Import server configuration successfully", "Konfigurace serveru úspěšně importována"),
("Export server configuration successfully", ""),
("Invalid server configuration", "Neplatná konfigurace serveru"), ("Invalid server configuration", "Neplatná konfigurace serveru"),
("Clipboard is empty", "Schránka je prázdná"), ("Clipboard is empty", "Schránka je prázdná"),
("Stop service", "Zastavit službu"), ("Stop service", "Zastavit službu"),

View File

@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable TCP Tunneling", "Slå TCP-tunneling til"), ("Enable TCP Tunneling", "Slå TCP-tunneling til"),
("IP Whitelisting", "IP-udgivelsesliste"), ("IP Whitelisting", "IP-udgivelsesliste"),
("ID/Relay Server", "ID/forbindelsesserver"), ("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"), ("Import server configuration successfully", "Importér serverkonfigurationen"),
("Export server configuration successfully", ""),
("Invalid server configuration", "Ugyldig serverkonfiguration"), ("Invalid server configuration", "Ugyldig serverkonfiguration"),
("Clipboard is empty", "Udklipsholderen er tom"), ("Clipboard is empty", "Udklipsholderen er tom"),
("Stop service", "Sluk for forbindelsesserveren"), ("Stop service", "Sluk for forbindelsesserveren"),

View File

@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable TCP Tunneling", "TCP-Tunnel aktivieren"), ("Enable TCP Tunneling", "TCP-Tunnel aktivieren"),
("IP Whitelisting", "IP-Whitelist"), ("IP Whitelisting", "IP-Whitelist"),
("ID/Relay Server", "ID/Vermittlungsserver"), ("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"), ("Import server configuration successfully", "Serverkonfiguration erfolgreich importiert"),
("Export server configuration successfully", ""),
("Invalid server configuration", "Ungültige Serverkonfiguration"), ("Invalid server configuration", "Ungültige Serverkonfiguration"),
("Clipboard is empty", "Zwischenablage ist leer"), ("Clipboard is empty", "Zwischenablage ist leer"),
("Stop service", "Vermittlungsdienst deaktivieren"), ("Stop service", "Vermittlungsdienst deaktivieren"),

View File

@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable TCP Tunneling", "Ebligi tunelado TCP"), ("Enable TCP Tunneling", "Ebligi tunelado TCP"),
("IP Whitelisting", "Listo de IP akceptataj"), ("IP Whitelisting", "Listo de IP akceptataj"),
("ID/Relay Server", "Identigila/Relajsa servilo"), ("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"), ("Import server configuration successfully", "Importi servilan agordon sukcese"),
("Export server configuration successfully", ""),
("Invalid server configuration", "Nevalida servila agordo"), ("Invalid server configuration", "Nevalida servila agordo"),
("Clipboard is empty", "La poŝo estas malplena"), ("Clipboard is empty", "La poŝo estas malplena"),
("Stop service", "Haltu servon"), ("Stop service", "Haltu servon"),

View File

@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable TCP Tunneling", "Habilitar tunel TCP"), ("Enable TCP Tunneling", "Habilitar tunel TCP"),
("IP Whitelisting", "Lista blanca de IP"), ("IP Whitelisting", "Lista blanca de IP"),
("ID/Relay Server", "Servidor ID/Relay"), ("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"), ("Import server configuration successfully", "Configuración de servidor importada con éxito"),
("Export server configuration successfully", ""),
("Invalid server configuration", "Configuración de servidor inválida"), ("Invalid server configuration", "Configuración de servidor inválida"),
("Clipboard is empty", "El portapapeles está vacío"), ("Clipboard is empty", "El portapapeles está vacío"),
("Stop service", "Parar servicio"), ("Stop service", "Parar servicio"),

View File

@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable TCP Tunneling", "Activer le tunneling TCP"), ("Enable TCP Tunneling", "Activer le tunneling TCP"),
("IP Whitelisting", "Liste blanche IP"), ("IP Whitelisting", "Liste blanche IP"),
("ID/Relay Server", "ID/Serveur Relais"), ("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"), ("Import server configuration successfully", "Configuration du serveur importée avec succès"),
("Export server configuration successfully", ""),
("Invalid server configuration", "Configuration du serveur non valide"), ("Invalid server configuration", "Configuration du serveur non valide"),
("Clipboard is empty", "Presse-papier vide"), ("Clipboard is empty", "Presse-papier vide"),
("Stop service", "Arrêter le service"), ("Stop service", "Arrêter le service"),

View File

@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable TCP Tunneling", "TCP Tunneling bekapcsolása"), ("Enable TCP Tunneling", "TCP Tunneling bekapcsolása"),
("IP Whitelisting", "IP Fehérlista"), ("IP Whitelisting", "IP Fehérlista"),
("ID/Relay Server", "ID/Relay Szerver"), ("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"), ("Import server configuration successfully", "Szerver konfiguráció sikeresen importálva"),
("Export server configuration successfully", ""),
("Invalid server configuration", "Érvénytelen szerver konfiguráció"), ("Invalid server configuration", "Érvénytelen szerver konfiguráció"),
("Clipboard is empty", "A vágólap üres"), ("Clipboard is empty", "A vágólap üres"),
("Stop service", "Szolgáltatás Kikapcsolása"), ("Stop service", "Szolgáltatás Kikapcsolása"),

View File

@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable TCP Tunneling", "Aktifkan TCP Tunneling"), ("Enable TCP Tunneling", "Aktifkan TCP Tunneling"),
("IP Whitelisting", "Daftar Putih IP"), ("IP Whitelisting", "Daftar Putih IP"),
("ID/Relay Server", "ID/Relay Server"), ("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"), ("Import server configuration successfully", "Impor konfigurasi server berhasil"),
("Export server configuration successfully", ""),
("Invalid server configuration", "Konfigurasi server tidak valid"), ("Invalid server configuration", "Konfigurasi server tidak valid"),
("Clipboard is empty", "Papan klip kosong"), ("Clipboard is empty", "Papan klip kosong"),
("Stop service", "Hentikan Layanan"), ("Stop service", "Hentikan Layanan"),

View File

@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable TCP Tunneling", "Abilita tunnel TCP"), ("Enable TCP Tunneling", "Abilita tunnel TCP"),
("IP Whitelisting", "IP autorizzati"), ("IP Whitelisting", "IP autorizzati"),
("ID/Relay Server", "Server ID/Relay"), ("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"), ("Import server configuration successfully", "Configurazione Server importata con successo"),
("Export server configuration successfully", ""),
("Invalid server configuration", "Configurazione Server non valida"), ("Invalid server configuration", "Configurazione Server non valida"),
("Clipboard is empty", "Gli appunti sono vuoti"), ("Clipboard is empty", "Gli appunti sono vuoti"),
("Stop service", "Arresta servizio"), ("Stop service", "Arresta servizio"),

View File

@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable TCP Tunneling", "TCPトンネリングを有効化"), ("Enable TCP Tunneling", "TCPトンネリングを有効化"),
("IP Whitelisting", "IPホワイトリスト"), ("IP Whitelisting", "IPホワイトリスト"),
("ID/Relay Server", "認証・中継サーバー"), ("ID/Relay Server", "認証・中継サーバー"),
("Import Server Conf", "サーバー設定をインポート"), ("Import Server Config", "サーバー設定をインポート"),
("Export Server Config", ""),
("Import server configuration successfully", "サーバー設定をインポートしました"), ("Import server configuration successfully", "サーバー設定をインポートしました"),
("Export server configuration successfully", ""),
("Invalid server configuration", "無効なサーバー設定です"), ("Invalid server configuration", "無効なサーバー設定です"),
("Clipboard is empty", "クリップボードは空です"), ("Clipboard is empty", "クリップボードは空です"),
("Stop service", "サービスを停止"), ("Stop service", "サービスを停止"),

View File

@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable TCP Tunneling", "TCP 터널링 활성화"), ("Enable TCP Tunneling", "TCP 터널링 활성화"),
("IP Whitelisting", "IP 화이트리스트"), ("IP Whitelisting", "IP 화이트리스트"),
("ID/Relay Server", "ID/Relay 서버"), ("ID/Relay Server", "ID/Relay 서버"),
("Import Server Conf", "서버 설정 가져오기"), ("Import Server Config", "서버 설정 가져오기"),
("Export Server Config", ""),
("Import server configuration successfully", "서버 설정 가져오기 성공"), ("Import server configuration successfully", "서버 설정 가져오기 성공"),
("Export server configuration successfully", ""),
("Invalid server configuration", "잘못된 서버 설정"), ("Invalid server configuration", "잘못된 서버 설정"),
("Clipboard is empty", "클립보드가 비어있습니다"), ("Clipboard is empty", "클립보드가 비어있습니다"),
("Stop service", "서비스 중단"), ("Stop service", "서비스 중단"),

View File

@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable TCP Tunneling", "TCP тунелдеуді қосу"), ("Enable TCP Tunneling", "TCP тунелдеуді қосу"),
("IP Whitelisting", "IP Ақ-тізімі"), ("IP Whitelisting", "IP Ақ-тізімі"),
("ID/Relay Server", "ID/Relay сербері"), ("ID/Relay Server", "ID/Relay сербері"),
("Import Server Conf", "Серверді импорттау"), ("Import Server Config", "Серверді импорттау"),
("Export Server Config", ""),
("Import server configuration successfully", "Сервердің конфигурациясы сәтті импортталды"), ("Import server configuration successfully", "Сервердің конфигурациясы сәтті импортталды"),
("Export server configuration successfully", ""),
("Invalid server configuration", "Жарамсыз сервердің конфигурациясы"), ("Invalid server configuration", "Жарамсыз сервердің конфигурациясы"),
("Clipboard is empty", "Көшіру-тақта бос"), ("Clipboard is empty", "Көшіру-тақта бос"),
("Stop service", "Сербесті тоқтату"), ("Stop service", "Сербесті тоқтату"),

View File

@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable TCP Tunneling", "Włącz tunelowanie TCP"), ("Enable TCP Tunneling", "Włącz tunelowanie TCP"),
("IP Whitelisting", "Biała lista IP"), ("IP Whitelisting", "Biała lista IP"),
("ID/Relay Server", "Serwer ID/Pośredniczący"), ("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ę"), ("Import server configuration successfully", "Importowanie konfiguracji serwera powiodło się"),
("Export server configuration successfully", ""),
("Invalid server configuration", "Nieprawidłowa konfiguracja serwera"), ("Invalid server configuration", "Nieprawidłowa konfiguracja serwera"),
("Clipboard is empty", "Schowek jest pusty"), ("Clipboard is empty", "Schowek jest pusty"),
("Stop service", "Zatrzymaj usługę"), ("Stop service", "Zatrzymaj usługę"),

View File

@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable TCP Tunneling", "Activar Túnel TCP"), ("Enable TCP Tunneling", "Activar Túnel TCP"),
("IP Whitelisting", "Whitelist de IP"), ("IP Whitelisting", "Whitelist de IP"),
("ID/Relay Server", "Servidor ID/Relay"), ("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"), ("Import server configuration successfully", "Configuração do servidor importada com sucesso"),
("Export server configuration successfully", ""),
("Invalid server configuration", "Configuração do servidor inválida"), ("Invalid server configuration", "Configuração do servidor inválida"),
("Clipboard is empty", "A área de transferência está vazia"), ("Clipboard is empty", "A área de transferência está vazia"),
("Stop service", "Parar serviço"), ("Stop service", "Parar serviço"),

View File

@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable TCP Tunneling", "Habilitar Tunelamento TCP"), ("Enable TCP Tunneling", "Habilitar Tunelamento TCP"),
("IP Whitelisting", "Whitelist de IP"), ("IP Whitelisting", "Whitelist de IP"),
("ID/Relay Server", "Servidor ID/Relay"), ("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"), ("Import server configuration successfully", "Configuração do servidor importada com sucesso"),
("Export server configuration successfully", ""),
("Invalid server configuration", "Configuração do servidor inválida"), ("Invalid server configuration", "Configuração do servidor inválida"),
("Clipboard is empty", "A área de transferência está vazia"), ("Clipboard is empty", "A área de transferência está vazia"),
("Stop service", "Parar serviço"), ("Stop service", "Parar serviço"),

View File

@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable TCP Tunneling", "Включить туннелирование TCP"), ("Enable TCP Tunneling", "Включить туннелирование TCP"),
("IP Whitelisting", "Список разрешенных IP-адресов"), ("IP Whitelisting", "Список разрешенных IP-адресов"),
("ID/Relay Server", "ID/Сервер ретрансляции"), ("ID/Relay Server", "ID/Сервер ретрансляции"),
("Import Server Conf", "Импортировать конфигурацию сервера"), ("Import Server Config", "Импортировать конфигурацию сервера"),
("Export Server Config", ""),
("Import server configuration successfully", "Конфигурация сервера успешно импортирована"), ("Import server configuration successfully", "Конфигурация сервера успешно импортирована"),
("Export server configuration successfully", ""),
("Invalid server configuration", "Недопустимая конфигурация сервера"), ("Invalid server configuration", "Недопустимая конфигурация сервера"),
("Clipboard is empty", "Буфер обмена пуст"), ("Clipboard is empty", "Буфер обмена пуст"),
("Stop service", "Остановить службу"), ("Stop service", "Остановить службу"),

View File

@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable TCP Tunneling", "Povoliť TCP tunelovanie"), ("Enable TCP Tunneling", "Povoliť TCP tunelovanie"),
("IP Whitelisting", "Zoznam povolených IP adries"), ("IP Whitelisting", "Zoznam povolených IP adries"),
("ID/Relay Server", "ID/Prepojovací server"), ("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á"), ("Import server configuration successfully", "Konfigurácia servera bola úspešne importovaná"),
("Export server configuration successfully", ""),
("Invalid server configuration", "Neplatná konfigurácia servera"), ("Invalid server configuration", "Neplatná konfigurácia servera"),
("Clipboard is empty", "Schránka je prázdna"), ("Clipboard is empty", "Schránka je prázdna"),
("Stop service", "Zastaviť službu"), ("Stop service", "Zastaviť službu"),

View File

@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable TCP Tunneling", ""), ("Enable TCP Tunneling", ""),
("IP Whitelisting", ""), ("IP Whitelisting", ""),
("ID/Relay Server", ""), ("ID/Relay Server", ""),
("Import Server Conf", ""), ("Import Server Config", ""),
("Export Server Config", ""),
("Import server configuration successfully", ""), ("Import server configuration successfully", ""),
("Export server configuration successfully", ""),
("Invalid server configuration", ""), ("Invalid server configuration", ""),
("Clipboard is empty", ""), ("Clipboard is empty", ""),
("Stop service", ""), ("Stop service", ""),

View File

@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable TCP Tunneling", "TCP Tüneline izin ver"), ("Enable TCP Tunneling", "TCP Tüneline izin ver"),
("IP Whitelisting", "İzinli IP listesi"), ("IP Whitelisting", "İzinli IP listesi"),
("ID/Relay Server", "ID/Relay Sunucusu"), ("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ı"), ("Import server configuration successfully", "Sunucu ayarları başarıyla içe aktarıldı"),
("Export server configuration successfully", ""),
("Invalid server configuration", "Geçersiz sunucu ayarı"), ("Invalid server configuration", "Geçersiz sunucu ayarı"),
("Clipboard is empty", "Kopyalanan geçici veri boş"), ("Clipboard is empty", "Kopyalanan geçici veri boş"),
("Stop service", "Servisi Durdur"), ("Stop service", "Servisi Durdur"),

View File

@ -29,8 +29,11 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable TCP Tunneling", "啟用 TCP 通道"), ("Enable TCP Tunneling", "啟用 TCP 通道"),
("IP Whitelisting", "IP 白名單"), ("IP Whitelisting", "IP 白名單"),
("ID/Relay Server", "ID/轉送伺服器"), ("ID/Relay Server", "ID/轉送伺服器"),
("Import Server Conf", "匯入伺服器設定"), ("Import Server Config", "匯入伺服器設定"),
("Export Server Config", "導出服務器配置"),
("Import server configuration successfully", "匯入伺服器設定成功"), ("Import server configuration successfully", "匯入伺服器設定成功"),
("Export server configuration successfully", ""),
("Export server configuration successfully", "導出服務器配置信息成功"),
("Invalid server configuration", "無效的伺服器設定"), ("Invalid server configuration", "無效的伺服器設定"),
("Clipboard is empty", "剪貼簿是空的"), ("Clipboard is empty", "剪貼簿是空的"),
("Stop service", "停止服務"), ("Stop service", "停止服務"),

View File

@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable TCP Tunneling", "Увімкнути тунелювання TCP"), ("Enable TCP Tunneling", "Увімкнути тунелювання TCP"),
("IP Whitelisting", "Список дозволених IP-адрес"), ("IP Whitelisting", "Список дозволених IP-адрес"),
("ID/Relay Server", "ID/Сервер ретрансляції"), ("ID/Relay Server", "ID/Сервер ретрансляції"),
("Import Server Conf", "Імпортувати конфігурацію сервера"), ("Import Server Config", "Імпортувати конфігурацію сервера"),
("Export Server Config", ""),
("Import server configuration successfully", "Конфігурацію сервера успішно імпортовано"), ("Import server configuration successfully", "Конфігурацію сервера успішно імпортовано"),
("Export server configuration successfully", ""),
("Invalid server configuration", "Недійсна конфігурація сервера"), ("Invalid server configuration", "Недійсна конфігурація сервера"),
("Clipboard is empty", "Буфер обміну порожній"), ("Clipboard is empty", "Буфер обміну порожній"),
("Stop service", "Зупинити службу"), ("Stop service", "Зупинити службу"),

View File

@ -29,8 +29,10 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Enable TCP Tunneling", "Cho phép TCP Tunneling"), ("Enable TCP Tunneling", "Cho phép TCP Tunneling"),
("IP Whitelisting", "Cho phép IP"), ("IP Whitelisting", "Cho phép IP"),
("ID/Relay Server", "Máy chủ ID/Relay"), ("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"), ("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ệ"), ("Invalid server configuration", "Cấu hình máy chủ không hợp lệ"),
("Clipboard is empty", "Khay nhớ tạm trống"), ("Clipboard is empty", "Khay nhớ tạm trống"),
("Stop service", "Dừng dịch vụ"), ("Stop service", "Dừng dịch vụ"),

View File

@ -878,6 +878,25 @@ fn get_install_info_with_subkey(subkey: String) -> (String, String, String, Stri
(subkey, path, start_menu, exe) (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<()> { pub fn update_me() -> ResultType<()> {
let (_, path, _, exe) = get_install_info(); let (_, path, _, exe) = get_install_info();
let src_exe = std::env::current_exe()?.to_str().unwrap_or("").to_owned(); 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} sc stop {app_name}
taskkill /F /IM {broker_exe} taskkill /F /IM {broker_exe}
taskkill /F /IM {app_name}.exe taskkill /F /IM {app_name}.exe
copy /Y \"{src_exe}\" \"{exe}\" {copy_exe}
\"{src_exe}\" --extract \"{path}\" \"{src_exe}\" --extract \"{path}\"
sc start {app_name} sc start {app_name}
{lic} {lic}
", ",
src_exe = src_exe, src_exe = src_exe,
exe = exe, copy_exe = copy_exe_cmd(&src_exe, &exe, &path),
broker_exe = crate::ui::win_privacy::INJECTED_PROCESS_EXE, broker_exe = crate::ui::win_privacy::INJECTED_PROCESS_EXE,
path = path, path = path,
app_name = crate::get_app_name(), 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(), 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 meta = std::fs::symlink_metadata(std::env::current_exe()?)?;
let size = meta.len() / 1024; 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, tmp_path = tmp_path,
app_name = crate::get_app_name(), app_name = crate::get_app_name(),
); );
let src_exe = std::env::current_exe()?.to_str().unwrap_or("").to_string();
let cmds = format!( let cmds = format!(
" "
{uninstall_str} {uninstall_str}
chcp 65001 chcp 65001
md \"{path}\" md \"{path}\"
{flutter_copy} {copy_exe}
copy /Y \"{src_exe}\" \"{exe}\"
copy /Y \"{ORIGIN_PROCESS_EXE}\" \"{path}\\{broker_exe}\" copy /Y \"{ORIGIN_PROCESS_EXE}\" \"{path}\\{broker_exe}\"
\"{src_exe}\" --extract \"{path}\" \"{src_exe}\" --extract \"{path}\"
reg add {subkey} /f reg add {subkey} /f
@ -1111,7 +1119,7 @@ sc delete {app_name}
", ",
uninstall_str=uninstall_str, uninstall_str=uninstall_str,
path=path, path=path,
src_exe=std::env::current_exe()?.to_str().unwrap_or(""), src_exe=src_exe,
exe=exe, exe=exe,
ORIGIN_PROCESS_EXE = crate::ui::win_privacy::ORIGIN_PROCESS_EXE, ORIGIN_PROCESS_EXE = crate::ui::win_privacy::ORIGIN_PROCESS_EXE,
broker_exe=crate::ui::win_privacy::INJECTED_PROCESS_EXE, broker_exe=crate::ui::win_privacy::INJECTED_PROCESS_EXE,
@ -1140,7 +1148,7 @@ sc delete {app_name}
} else { } else {
&dels &dels
}, },
flutter_copy = flutter_copy, copy_exe = copy_exe_cmd(&src_exe, &exe, &path),
); );
run_cmds(cmds, debug, "install")?; run_cmds(cmds, debug, "install")?;
std::thread::sleep(std::time::Duration::from_millis(2000)); std::thread::sleep(std::time::Duration::from_millis(2000));
@ -1478,7 +1486,13 @@ pub fn run_uac(exe: &str, arg: &str) -> ResultType<bool> {
} }
pub fn check_super_user_permission() -> ResultType<bool> { pub fn check_super_user_permission() -> ResultType<bool> {
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<bool> { pub fn elevate(arg: &str) -> ResultType<bool> {