From 48a9d208e6421e46ca9483a05463d73a8acbd252 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Thu, 28 Nov 2024 14:44:24 +0800 Subject: [PATCH 1/7] Label text optimization --- v2rayN/ServiceLib/Resx/ResUI.Designer.cs | 2 +- v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx | 2 +- v2rayN/ServiceLib/Resx/ResUI.resx | 2 +- v2rayN/ServiceLib/Resx/ResUI.ru.resx | 2 +- v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx | 2 +- v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs index 86355997..87415bd1 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs +++ b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs @@ -3140,7 +3140,7 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Linux system sudo password 的本地化字符串。 + /// 查找类似 System sudo password 的本地化字符串。 /// public static string TbSettingsLinuxSudoPassword { get { diff --git a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx index 3b90ede6..830cefe5 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx @@ -1364,7 +1364,7 @@ (Domain or IP or ProcName) and Port and Protocol and InboundTag => OutboundTag - Linux system sudo password + System sudo password The password is encrypted and stored only in local files. diff --git a/v2rayN/ServiceLib/Resx/ResUI.resx b/v2rayN/ServiceLib/Resx/ResUI.resx index 50f47431..3f006a0b 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.resx @@ -1364,7 +1364,7 @@ Remarks Memo - Linux system sudo password + System sudo password The password is encrypted and stored only in local files. diff --git a/v2rayN/ServiceLib/Resx/ResUI.ru.resx b/v2rayN/ServiceLib/Resx/ResUI.ru.resx index 77d2314b..493fb702 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.ru.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.ru.resx @@ -1364,7 +1364,7 @@ Remote (WebDAV) - Linux system sudo password + System sudo password The password is encrypted and stored only in local files. diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx index e6c33ce8..d5fd572e 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx @@ -1361,7 +1361,7 @@ 备注备忘 - Linux系统的sudo密码 + 系统的sudo密码 密码已加密且只存储在本地文件中,无密码则每次都要输入 diff --git a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx index 05aaf56e..87e5be51 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx @@ -1361,7 +1361,7 @@ 混淆密碼(obfs password) - Linux系統的sudo密碼 + 系統的sudo密碼 密碼已加密且只儲存在本機檔案中,無密碼則每次都要輸入 From 558e5bb340f9fc9129cdac69f427e465e21e2e0d Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Fri, 29 Nov 2024 10:31:57 +0800 Subject: [PATCH 2/7] Improve tun for linux --- v2rayN/ServiceLib/Handler/CoreHandler.cs | 27 +++++++++++++++++------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/v2rayN/ServiceLib/Handler/CoreHandler.cs b/v2rayN/ServiceLib/Handler/CoreHandler.cs index ec4aa60c..4710dc4c 100644 --- a/v2rayN/ServiceLib/Handler/CoreHandler.cs +++ b/v2rayN/ServiceLib/Handler/CoreHandler.cs @@ -334,7 +334,7 @@ namespace ServiceLib.Handler } try { - proc?.Kill(); + proc?.Kill(true); } catch (Exception) { @@ -375,7 +375,7 @@ namespace ServiceLib.Handler private async Task KillProcessAsLinuxSudo() { - var cmdLine = $"kill -9 {_linuxSudoPid}"; + var cmdLine = $"kill {_linuxSudoPid}"; var shFilePath = await CreateLinuxShellFile(cmdLine, "kill_as_sudo.sh"); Process proc = new() { @@ -392,11 +392,18 @@ namespace ServiceLib.Handler if (_config.TunModeItem.LinuxSudoPwd.IsNotEmpty()) { - var pwd = DesUtils.Decrypt(_config.TunModeItem.LinuxSudoPwd); - await Task.Delay(10); - await proc.StandardInput.WriteLineAsync(pwd); - await Task.Delay(10); - await proc.StandardInput.WriteLineAsync(pwd); + try + { + var pwd = DesUtils.Decrypt(_config.TunModeItem.LinuxSudoPwd); + await Task.Delay(10); + await proc.StandardInput.WriteLineAsync(pwd); + await Task.Delay(10); + await proc.StandardInput.WriteLineAsync(pwd); + } + catch (Exception) + { + // ignored + } } var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(10)); @@ -411,7 +418,11 @@ namespace ServiceLib.Handler File.Delete(shFilePath); var sb = new StringBuilder(); sb.AppendLine("#!/bin/sh"); - if (_config.TunModeItem.LinuxSudoPwd.IsNullOrEmpty()) + if (AppHandler.Instance.IsAdministrator) + { + sb.AppendLine($"{cmdLine}"); + } + else if (_config.TunModeItem.LinuxSudoPwd.IsNullOrEmpty()) { sb.AppendLine($"pkexec {cmdLine}"); } From 1ff4839be13cf0efcad04dbd9682c03a3d6059f3 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Fri, 29 Nov 2024 11:31:22 +0800 Subject: [PATCH 3/7] Bug fix https://github.com/2dust/v2rayN/issues/6160 --- v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs | 6 ++++-- v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs | 8 ++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs b/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs index 3be5dcaa..9b016ca6 100644 --- a/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs @@ -283,7 +283,6 @@ namespace ServiceLib.ViewModels try { Logging.SaveLog("MyAppExit Begin"); - //if (blWindowsShutDown) await SysProxyHandler.UpdateSysProxy(_config, true); await ConfigHandler.SaveConfig(_config); @@ -297,7 +296,10 @@ namespace ServiceLib.ViewModels catch { } finally { - _updateView?.Invoke(EViewAction.Shutdown, null); + if (!blWindowsShutDown) + { + _updateView?.Invoke(EViewAction.Shutdown, null); + } } } diff --git a/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs b/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs index eebc9362..95f587bf 100644 --- a/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs +++ b/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs @@ -21,6 +21,7 @@ namespace v2rayN.Desktop.Views private WindowNotificationManager? _manager; private CheckUpdateView? _checkUpdateView; private BackupAndRestoreView? _backupAndRestoreView; + private bool _blCloseByUser = false; public MainWindow() { @@ -279,6 +280,11 @@ namespace v2rayN.Desktop.Views protected override async void OnClosing(WindowClosingEventArgs e) { + if (_blCloseByUser) + { + return; + } + Logging.SaveLog("OnClosing -> " + e.CloseReason.ToString()); switch (e.CloseReason) @@ -374,6 +380,8 @@ namespace v2rayN.Desktop.Views { return; } + + _blCloseByUser = true; StorageUI(); await ViewModel?.MyAppExitAsync(false); From 1c6323315ba4701f36308622db8eaa441cfd831a Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Fri, 29 Nov 2024 11:43:53 +0800 Subject: [PATCH 4/7] up 7.2.3 --- v2rayN/ServiceLib/ServiceLib.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v2rayN/ServiceLib/ServiceLib.csproj b/v2rayN/ServiceLib/ServiceLib.csproj index 48f0e359..11735c0d 100644 --- a/v2rayN/ServiceLib/ServiceLib.csproj +++ b/v2rayN/ServiceLib/ServiceLib.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 7.2.2 + 7.2.3 From f685682214c7873ffaf9e19606afb7f36b123139 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Fri, 29 Nov 2024 19:21:09 +0800 Subject: [PATCH 5/7] Code clean --- .../ServiceLib/Handler/AutoStartupHandler.cs | 2 +- v2rayN/ServiceLib/Handler/CoreHandler.cs | 32 ++++--------------- v2rayN/ServiceLib/ServiceLib.csproj | 2 +- .../CoreConfig/CoreConfigSingboxService.cs | 4 +-- .../ServiceLib/Services/SpeedtestService.cs | 6 ++-- .../ViewModels/OptionSettingViewModel.cs | 2 +- 6 files changed, 14 insertions(+), 34 deletions(-) diff --git a/v2rayN/ServiceLib/Handler/AutoStartupHandler.cs b/v2rayN/ServiceLib/Handler/AutoStartupHandler.cs index 6708a38e..12dc2921 100644 --- a/v2rayN/ServiceLib/Handler/AutoStartupHandler.cs +++ b/v2rayN/ServiceLib/Handler/AutoStartupHandler.cs @@ -25,7 +25,7 @@ namespace ServiceLib.Handler await SetTaskLinux(); } } - else if(Utils.IsOSX()) + else if (Utils.IsOSX()) { //TODO } diff --git a/v2rayN/ServiceLib/Handler/CoreHandler.cs b/v2rayN/ServiceLib/Handler/CoreHandler.cs index 4710dc4c..a5073dc0 100644 --- a/v2rayN/ServiceLib/Handler/CoreHandler.cs +++ b/v2rayN/ServiceLib/Handler/CoreHandler.cs @@ -98,15 +98,11 @@ namespace ServiceLib.Handler if (_process != null) { await KillProcess(_process); - _process.Dispose(); - _process = null; } if (_processPre != null) { await KillProcess(_processPre); - _processPre.Dispose(); - _processPre = null; } if (_linuxSudoPid > 0) @@ -125,8 +121,7 @@ namespace ServiceLib.Handler { try { - var _p = Process.GetProcessById(pid); - await KillProcess(_p); + await KillProcess(Process.GetProcessById(pid)); } catch (Exception ex) { @@ -332,26 +327,11 @@ namespace ServiceLib.Handler { return; } - try - { - proc?.Kill(true); - } - catch (Exception) - { - // ignored - } + try { proc?.Kill(true); } catch { } + try { proc?.Close(); } catch { } + try { proc?.Dispose(); } catch { } + proc = null; await Task.Delay(100); - if (proc?.HasExited == false) - { - try - { - proc?.Kill(); - } - catch (Exception) - { - // ignored - } - } } #endregion Process @@ -408,7 +388,7 @@ namespace ServiceLib.Handler var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(10)); await proc.WaitForExitAsync(timeout.Token); - await Task.Delay(1000); + await Task.Delay(3000); } private async Task CreateLinuxShellFile(string cmdLine, string fileName) diff --git a/v2rayN/ServiceLib/ServiceLib.csproj b/v2rayN/ServiceLib/ServiceLib.csproj index 11735c0d..48f0e359 100644 --- a/v2rayN/ServiceLib/ServiceLib.csproj +++ b/v2rayN/ServiceLib/ServiceLib.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 7.2.3 + 7.2.2 diff --git a/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs b/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs index 4f9245b4..3cdcbe3d 100644 --- a/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs +++ b/v2rayN/ServiceLib/Services/CoreConfig/CoreConfigSingboxService.cs @@ -26,7 +26,7 @@ namespace ServiceLib.Services.CoreConfig ret.Msg = ResUI.CheckServerSettings; return ret; } - if (node.GetNetwork() is nameof(ETransport.kcp) or nameof(ETransport.xhttp)) + if (node.GetNetwork() is nameof(ETransport.kcp) or nameof(ETransport.xhttp)) { ret.Msg = ResUI.Incorrectconfiguration + $" - {node.GetNetwork()}"; return ret; @@ -548,7 +548,7 @@ namespace ServiceLib.Services.CoreConfig } var tunInbound = JsonUtils.Deserialize(Utils.GetEmbedText(Global.TunSingboxInboundFileName)) ?? new Inbound4Sbox { }; - tunInbound.interface_name = Utils.IsOSX()? $"utun{new Random().Next(99)}": "singbox_tun"; + tunInbound.interface_name = Utils.IsOSX() ? $"utun{new Random().Next(99)}" : "singbox_tun"; tunInbound.mtu = _config.TunModeItem.Mtu; tunInbound.strict_route = _config.TunModeItem.StrictRoute; tunInbound.stack = _config.TunModeItem.Stack; diff --git a/v2rayN/ServiceLib/Services/SpeedtestService.cs b/v2rayN/ServiceLib/Services/SpeedtestService.cs index e257d421..d0fdd775 100644 --- a/v2rayN/ServiceLib/Services/SpeedtestService.cs +++ b/v2rayN/ServiceLib/Services/SpeedtestService.cs @@ -185,7 +185,7 @@ namespace ServiceLib.Services { if (pid > 0) { - CoreHandler.Instance.CoreStopPid(pid); + await CoreHandler.Instance.CoreStopPid(pid); } await ProfileExHandler.Instance.SaveTo(); } @@ -252,7 +252,7 @@ namespace ServiceLib.Services if (pid > 0) { - CoreHandler.Instance.CoreStopPid(pid); + await CoreHandler.Instance.CoreStopPid(pid); } UpdateFunc("", ResUI.SpeedtestingCompleted); await ProfileExHandler.Instance.SaveTo(); @@ -317,7 +317,7 @@ namespace ServiceLib.Services if (pid > 0) { - CoreHandler.Instance.CoreStopPid(pid); + await CoreHandler.Instance.CoreStopPid(pid); } UpdateFunc("", ResUI.SpeedtestingCompleted); await ProfileExHandler.Instance.SaveTo(); diff --git a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs index 87fc6237..53fe1df6 100644 --- a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs @@ -405,4 +405,4 @@ namespace ServiceLib.ViewModels } } } -} +} \ No newline at end of file From e4d3a98aa814add980d575973306b61a76999695 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Sat, 30 Nov 2024 10:58:53 +0800 Subject: [PATCH 6/7] Fixed the problem of traffic statistics api url --- v2rayN/ServiceLib/Handler/AppHandler.cs | 9 ++++++++- v2rayN/ServiceLib/Handler/CoreHandler.cs | 13 +++++++------ .../Services/Statistics/StatisticsSingboxService.cs | 8 +++----- .../Services/Statistics/StatisticsXrayService.cs | 5 ++--- .../ServiceLib/ViewModels/OptionSettingViewModel.cs | 1 + 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/v2rayN/ServiceLib/Handler/AppHandler.cs b/v2rayN/ServiceLib/Handler/AppHandler.cs index 9615b73a..447c31f9 100644 --- a/v2rayN/ServiceLib/Handler/AppHandler.cs +++ b/v2rayN/ServiceLib/Handler/AppHandler.cs @@ -27,7 +27,7 @@ get { _statePort2 ??= Utils.GetFreePort(GetLocalPort(EInboundProtocol.api2)); - return _statePort2.Value; + return _statePort2.Value + (_config.TunModeItem.EnableTun ? 1 : 0); } } @@ -79,6 +79,13 @@ return true; } + public bool Reset() + { + _statePort = null; + _statePort2 = null; + return true; + } + #endregion Init #region Config diff --git a/v2rayN/ServiceLib/Handler/CoreHandler.cs b/v2rayN/ServiceLib/Handler/CoreHandler.cs index a5073dc0..78bc505e 100644 --- a/v2rayN/ServiceLib/Handler/CoreHandler.cs +++ b/v2rayN/ServiceLib/Handler/CoreHandler.cs @@ -97,12 +97,12 @@ namespace ServiceLib.Handler { if (_process != null) { - await KillProcess(_process); + _process = await KillProcess(_process); } if (_processPre != null) { - await KillProcess(_processPre); + _processPre = await KillProcess(_processPre); } if (_linuxSudoPid > 0) @@ -321,17 +321,18 @@ namespace ServiceLib.Handler } } - private async Task KillProcess(Process? proc) + private async Task KillProcess(Process? proc) { if (proc is null) { - return; + return null; } try { proc?.Kill(true); } catch { } try { proc?.Close(); } catch { } try { proc?.Dispose(); } catch { } - proc = null; + await Task.Delay(100); + return null; } #endregion Process @@ -394,7 +395,7 @@ namespace ServiceLib.Handler private async Task CreateLinuxShellFile(string cmdLine, string fileName) { //Shell scripts - var shFilePath = Utils.GetBinPath(fileName); + var shFilePath = Utils.GetBinPath(AppHandler.Instance.IsAdministrator ? "root_" + fileName : fileName); File.Delete(shFilePath); var sb = new StringBuilder(); sb.AppendLine("#!/bin/sh"); diff --git a/v2rayN/ServiceLib/Services/Statistics/StatisticsSingboxService.cs b/v2rayN/ServiceLib/Services/Statistics/StatisticsSingboxService.cs index a051fc95..e8f294e4 100644 --- a/v2rayN/ServiceLib/Services/Statistics/StatisticsSingboxService.cs +++ b/v2rayN/ServiceLib/Services/Statistics/StatisticsSingboxService.cs @@ -8,9 +8,9 @@ namespace ServiceLib.Services.Statistics private Config _config; private bool _exitFlag; private ClientWebSocket? webSocket; - private string url = string.Empty; private Action? _updateFunc; - + private string Url => $"ws://{Global.Loopback}:{AppHandler.Instance.StatePort2}/traffic"; + public StatisticsSingboxService(Config config, Action updateFunc) { _config = config; @@ -26,12 +26,10 @@ namespace ServiceLib.Services.Statistics try { - url = $"ws://{Global.Loopback}:{AppHandler.Instance.StatePort2}/traffic"; - if (webSocket == null) { webSocket = new ClientWebSocket(); - await webSocket.ConnectAsync(new Uri(url), CancellationToken.None); + await webSocket.ConnectAsync(new Uri(Url), CancellationToken.None); } } catch { } diff --git a/v2rayN/ServiceLib/Services/Statistics/StatisticsXrayService.cs b/v2rayN/ServiceLib/Services/Statistics/StatisticsXrayService.cs index 274e0f2e..fee5721f 100644 --- a/v2rayN/ServiceLib/Services/Statistics/StatisticsXrayService.cs +++ b/v2rayN/ServiceLib/Services/Statistics/StatisticsXrayService.cs @@ -3,18 +3,17 @@ public class StatisticsXrayService { private const long linkBase = 1024; - private string _url; private ServerSpeedItem _serverSpeedItem = new(); private Config _config; private bool _exitFlag; private Action? _updateFunc; + private string Url => $"{Global.HttpProtocol}{Global.Loopback}:{AppHandler.Instance.StatePort}/debug/vars"; public StatisticsXrayService(Config config, Action updateFunc) { _config = config; _updateFunc = updateFunc; _exitFlag = false; - _url = $"{Global.HttpProtocol}{Global.Loopback}:{AppHandler.Instance.StatePort}/debug/vars"; Task.Run(Run); } @@ -36,7 +35,7 @@ continue; } - var result = await HttpClientHelper.Instance.TryGetAsync(_url); + var result = await HttpClientHelper.Instance.TryGetAsync(Url); if (result != null) { var server = ParseOutput(result) ?? new ServerSpeedItem(); diff --git a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs index 53fe1df6..1a8de48a 100644 --- a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs @@ -356,6 +356,7 @@ namespace ServiceLib.ViewModels if (await ConfigHandler.SaveConfig(_config) == 0) { await AutoStartupHandler.UpdateTask(_config); + AppHandler.Instance.Reset(); NoticeHandler.Instance.Enqueue(needReboot ? ResUI.NeedRebootTips : ResUI.OperationSuccess); _updateView?.Invoke(EViewAction.CloseWindow, null); From d3a0b44247ca1745158c16d6bb668a3ea3af3063 Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Sat, 30 Nov 2024 13:49:26 +0800 Subject: [PATCH 7/7] Bug fix https://github.com/2dust/v2rayN/issues/6182 --- v2rayN/ServiceLib/Handler/SysProxy/SysProxyHandler.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/v2rayN/ServiceLib/Handler/SysProxy/SysProxyHandler.cs b/v2rayN/ServiceLib/Handler/SysProxy/SysProxyHandler.cs index 54b6ab3b..8f1a0446 100644 --- a/v2rayN/ServiceLib/Handler/SysProxy/SysProxyHandler.cs +++ b/v2rayN/ServiceLib/Handler/SysProxy/SysProxyHandler.cs @@ -66,10 +66,10 @@ private static void GetWindowsProxyString(Config config, int port, int portSocks, out string strProxy, out string strExceptions) { - strExceptions = ""; + strExceptions = $"{config.ConstItem.DefIEProxyExceptions};{config.SystemProxyItem.SystemProxyExceptions}"; if (config.SystemProxyItem.NotProxyLocalAddress) { - strExceptions = $";{config.ConstItem.DefIEProxyExceptions};{config.SystemProxyItem.SystemProxyExceptions}"; + strExceptions = $";{strExceptions}"; } strProxy = string.Empty;