private async void UpdateACL(bool useProxy) { if (useProxy && ServerComboBox.SelectedIndex == -1) { MessageBoxX.Show(i18N.Translate("Please select a server first")); return; } Enabled = false; StatusText(i18N.TranslateFormat("Updating {0}", "ACL")); try { if (useProxy) { var mode = new Models.Mode { Remark = "ProxyUpdate", Type = 5 }; State = State.Starting; await MainController.Start(ServerComboBox.SelectedItem as Server, mode); } var req = WebUtil.CreateRequest(Global.Settings.ACL); if (useProxy) { req.Proxy = new WebProxy($"http://127.0.0.1:{Global.Settings.HTTPLocalPort}"); } await WebUtil.DownloadFileAsync(req, Path.Combine(Global.NetchDir, "bin\\default.acl")); NotifyTip(i18N.Translate("ACL updated successfully")); } catch (Exception e) { NotifyTip(i18N.Translate("ACL update failed") + "\n" + e.Message, info: false); Logging.Error("更新 ACL 失败!" + e); } finally { if (useProxy) { await MainController.Stop(); State = State.Stopped; } StatusText(); Enabled = true; } }
private void AddButton_Click(object sender, EventArgs e) { if (string.IsNullOrWhiteSpace(RemarkTextBox.Text)) { MessageBoxX.Show(i18N.Translate("Remark can not be empty")); return; } if (string.IsNullOrWhiteSpace(LinkTextBox.Text)) { MessageBoxX.Show(i18N.Translate("Link can not be empty")); return; } if (!LinkTextBox.Text.StartsWith("HTTP://", StringComparison.OrdinalIgnoreCase) && !LinkTextBox.Text.StartsWith("HTTPS://", StringComparison.OrdinalIgnoreCase)) { MessageBoxX.Show(i18N.Translate("Link must start with http:// or https://")); return; } if (SelectedIndex == -1) { if (Global.Settings.SubscribeLink.Any(link => link.Remark.Equals(RemarkTextBox.Text))) { MessageBoxX.Show("Remark Name Duplicate!"); return; } Global.Settings.SubscribeLink.Add(new SubscribeLink { Enable = true, Remark = RemarkTextBox.Text, Link = LinkTextBox.Text, UserAgent = UserAgentTextBox.Text }); } else { var subscribeLink = Global.Settings.SubscribeLink[SelectedIndex]; RenameServers(subscribeLink.Remark, RemarkTextBox.Text); subscribeLink.Link = LinkTextBox.Text; subscribeLink.Remark = RemarkTextBox.Text; subscribeLink.UserAgent = UserAgentTextBox.Text; } MessageBoxX.Show(i18N.Translate("Saved")); InitSubscribeLink(); }
private void DeleteToolStripMenuItem_Click(object sender, EventArgs e) { if (MessageBoxX.Show(i18N.Translate("Delete or not ? Will clean up the corresponding group of items in the server list"), confirm: true) != DialogResult.OK) { return; } var subscribeLink = Global.Settings.SubscribeLink[SelectedIndex]; DeleteServers(subscribeLink.Remark); Global.Settings.SubscribeLink.Remove(subscribeLink); InitSubscribeLink(); }
private void Exit(bool forceExit = false) { if (IsDisposed) { return; } // 已启动 if (State != State.Waiting && State != State.Stopped) { if (forceExit) { ControlFun(); } else { if (!Global.Settings.StopWhenExited) { // 未开启自动停止 MessageBoxX.Show(i18N.Translate("Please press Stop button first")); Visible = true; ShowInTaskbar = true; // 显示在系统任务栏 WindowState = FormWindowState.Normal; // 还原窗体 NotifyIcon.Visible = true; // 托盘图标隐藏 return; } } } NotifyIcon.Visible = false; Hide(); Task.Run(() => { for (var i = 0; i < 16; i++) { if (State == State.Waiting || State == State.Stopped) { break; } Thread.Sleep(250); } SaveConfigs(); UpdateStatus(State.Terminating); Dispose(); Environment.Exit(Environment.ExitCode); }); }
private void updateACLWithProxyToolStripMenuItem_Click(object sender, EventArgs e) { updateACLWithProxyToolStripMenuItem.Enabled = false; // 当前 ServerComboBox 中至少有一项 if (ServerComboBox.SelectedIndex == -1) { MessageBoxX.Show(i18N.Translate("Please select a server first")); return; } MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = false; ControlButton.Text = "..."; Task.Run(() => { var mode = new Models.Mode { Remark = "ProxyUpdate", Type = 5 }; _mainController = new MainController(); _mainController.Start(ServerComboBox.SelectedItem as Models.Server, mode); using var client = new WebClient(); client.Proxy = new WebProxy($"http://127.0.0.1:{Global.Settings.HTTPLocalPort}"); StatusText(i18N.Translate("Updating in the background")); try { client.DownloadFile(Global.Settings.ACL, "bin\\default.acl"); NotifyIcon.ShowBalloonTip(5, UpdateChecker.Name, i18N.Translate("ACL updated successfully"), ToolTipIcon.Info); } catch (Exception e) { Logging.Error("使用代理更新 ACL 失败!" + e); MessageBoxX.Show(i18N.Translate("ACL update failed") + "\n" + e); } finally { State = State.Waiting; _mainController.Stop(); } }); }
private void DeleteToolStripMenuItem_Click(object sender, EventArgs e) { if (MessageBoxX.Show(i18N.Translate("Delete or not ? Will clean up the corresponding group of items in the server list"), confirm: true) != DialogResult.OK) { return; } var viewItem = SubscribeLinkListView.SelectedItems[0]; var subscribeLink = Global.Settings.SubscribeLink[viewItem.Index]; DeleteServersInGroup(subscribeLink.Remark); Global.Settings.SubscribeLink.Remove(subscribeLink); SubscribeLinkListView.Items.Remove(viewItem); ResetEditingGroup(); }
private void DeleteModePictureBox_Click(object sender, EventArgs e) { // 当前ModeComboBox中至少有一项 if (ModeComboBox.Items.Count <= 0 || ModeComboBox.SelectedIndex == -1) { MessageBoxX.Show(i18N.Translate("Please select a mode first")); return; } var selectedMode = (Models.Mode)ModeComboBox.SelectedItem; this.ModeComboBox.Items.Remove(selectedMode); Modes.Delete(selectedMode); SelectLastMode(); }
private async void NewVersionLabel_Click(object sender, EventArgs e) { if (!_updater.LatestVersionDownloadUrl.Contains("Netch")) { Utils.Utils.Open(_updater.LatestVersionUrl); return; } if (MessageBoxX.Show(i18N.Translate("Download and install now?"), confirm: true) != DialogResult.OK) { return; } NotifyTip(i18N.Translate("Start downloading new version")); var fileName = Path.GetFileName(new Uri(_updater.LatestVersionDownloadUrl).LocalPath); fileName = fileName.Insert(fileName.LastIndexOf('.'), _updater.LatestVersionNumber); var fileFullPath = Path.Combine(Global.NetchDir, "data", fileName); try { if (!File.Exists(fileFullPath)) { await WebUtil.DownloadFileAsync(WebUtil.CreateRequest(_updater.LatestVersionDownloadUrl), fileFullPath); } RunUpdater(); } catch (Exception exception) { NotifyTip($"{i18N.Translate("Download update failed")}\n{exception.Message}"); Logging.Error($"下载更新失败 {exception}"); } void RunUpdater() { // if debugging process stopped, debugger will kill child processes!!!! // 调试进程结束,调试器将会杀死子进程 // uncomment if(!Debugger.isAttach) block in NetchUpdater Project's main() method and attach to NetchUpdater process to debug // 在 NetchUpdater 项目的 main() 方法中取消注释 if(!Debugger.isAttach)块,并附加到 NetchUpdater 进程进行调试 Process.Start(new ProcessStartInfo { FileName = Path.Combine(Global.NetchDir, "NetchUpdater.exe"), Arguments = $"{Global.Settings.UDPSocketPort}|{fileFullPath}|{Global.NetchDir}" }); } }
private void EditServerPictureBox_Click(object sender, EventArgs e) { // 当前ServerComboBox中至少有一项 if (ServerComboBox.SelectedIndex == -1) { MessageBoxX.Show(i18N.Translate("Please select a server first")); return; } Hide(); var server = Global.Settings.Server[ServerComboBox.SelectedIndex]; ServerHelper.GetUtilByTypeName(server.Type).Edit(server); InitServer(); Configuration.Save(); Show(); }
private async void NewVersionLabel_Click(object sender, EventArgs e) { if (MessageBoxX.Show(i18N.Translate("Download and install now?"), confirm: true) != DialogResult.OK) { return; } NotifyTip(i18N.Translate("Start downloading new version")); var fileName = $"Netch{_updater.LatestVersionNumber}.zip"; var fileFullPath = Path.Combine(Global.NetchDir, "data", fileName); if (File.Exists(fileFullPath)) { if (Utils.Utils.IsZipValid(fileFullPath)) { // if debugging process stopped, debugger will kill child processes!!!! // 调试进程结束,调试器将会杀死子进程 // uncomment if(!Debugger.isAttach) block in NetchUpdater Project's main() method and attach to NetchUpdater process to debug // 在 NetchUpdater 项目的 main() 方法中取消注释 if(!Debugger.isAttach)块,并附加到 NetchUpdater 进程进行调试 Process.Start(new ProcessStartInfo { FileName = Path.Combine(Global.NetchDir, "NetchUpdater.exe"), Arguments = $"{Global.Settings.UDPSocketPort} {fileFullPath} {Global.NetchDir}" }); return; } File.Delete(fileFullPath); } await WebUtil.DownloadFileAsync(WebUtil.CreateRequest(_updater.LatestVersionDownloadUrl), fileFullPath); if (Utils.Utils.IsZipValid(fileFullPath)) { Process.Start(new ProcessStartInfo { FileName = "cmd", Arguments = $"/c {Path.Combine(Global.NetchDir, "NetchUpdater.exe")} {Global.Settings.UDPSocketPort} {fileFullPath} {Global.NetchDir}" }); } else { NotifyTip("Download update failed"); } }
private void UninstallServiceToolStripMenuItem_Click(object sender, EventArgs e) { Enabled = false; StatusText(i18N.Translate("Uninstalling Service")); Task.Run(() => { var driver = $"{Environment.SystemDirectory}\\drivers\\netfilter2.sys"; if (File.Exists(driver)) { try { var service = new ServiceController("netfilter2"); if (service.Status == ServiceControllerStatus.Running) { service.Stop(); service.WaitForStatus(ServiceControllerStatus.Stopped); } } catch (Exception) { // 跳过 } try { NFAPI.nf_unRegisterDriver("netfilter2"); File.Delete(driver); MessageBoxX.Show(i18N.Translate("Service has been uninstalled"), owner: this); } catch (Exception ex) { MessageBoxX.Show(i18N.Translate("Error") + i18N.Translate(": ") + ex, info: false, owner: this); } } else { MessageBoxX.Show(i18N.Translate("Service has been uninstalled"), owner: this); } Enabled = true; }); }
private void DeleteToolStripMenuItem_Click(object sender, EventArgs e) { if (MessageBoxX.Show(i18N.Translate("Delete or not ? Will clean up the corresponding group of items in the server list"), confirm: true) == DialogResult.OK) { if (SubscribeLinkListView.SelectedItems.Count > 0) { for (var i = SubscribeLinkListView.SelectedItems.Count - 1; i >= 0; i--) { var item = SubscribeLinkListView.SelectedItems[i]; DeleteServersInGroup(item.SubItems[0].Text); Global.Settings.SubscribeLink.RemoveAt(item.Index); SubscribeLinkListView.Items.Remove(item); ResetEditingGroup(); } } } }
static void CheckPort(string portName, int port, int originPort, PortType portType = PortType.Both) { if (port <= 0 || port > 65536) { throw new FormatException(); } if (port == originPort) { return; } if (PortHelper.PortInUse(port, portType)) { MessageBoxX.Show(i18N.TranslateFormat("The {0} port is in use.", portName)); throw new PortInUseException(); } }
private void AddButton_Click(object sender, EventArgs e) { if (!string.IsNullOrEmpty(IPTextBox.Text)) { if (IPAddress.TryParse(IPTextBox.Text, out var address)) { IPListBox.Items.Add(string.Format("{0}/{1}", address, PrefixComboBox.SelectedItem)); } else { MessageBoxX.Show(i18N.Translate("Please enter a correct IP address")); } } else { MessageBoxX.Show(i18N.Translate("Please enter an IP")); } }
private void DeleteServerPictureBox_Click(object sender, EventArgs e) { // 当前 ServerComboBox 中至少有一项 if (ServerComboBox.SelectedIndex == -1) { MessageBoxX.Show(i18N.Translate("Please select a server first")); return; } var index = ServerComboBox.SelectedIndex; Global.Settings.Server.Remove(ServerComboBox.SelectedItem as Server); InitServer(); Configuration.Save(); if (ServerComboBox.Items.Count > 0) { ServerComboBox.SelectedIndex = index != 0 ? index - 1 : index; } }
private void CopyLinkPictureBox_Click(object sender, EventArgs e) { // 当前ServerComboBox中至少有一项 if (ServerComboBox.SelectedIndex != -1) { var selectedMode = (Models.Server)ServerComboBox.SelectedItem; try { //听说巨硬BUG经常会炸,所以Catch一下 :D Clipboard.SetText(ShareLink.GetShareLink(selectedMode)); } catch (Exception) { } } else { MessageBoxX.Show(i18N.Translate("Please select a server first")); } }
private void CleanDNSCacheToolStripMenuItem_Click(object sender, EventArgs e) { var bak_State = State; var bak_StateText = StatusLabel.Text; try { Enabled = false; DNS.Cache.Clear(); MessageBoxX.Show(i18N.Translate("DNS cache cleanup succeeded"), owner: this); StatusText(i18N.Translate("DNS cache cleanup succeeded")); Enabled = true; } finally { State = bak_State; StatusLabel.Text = bak_StateText; } }
private void Exit(bool forceExit = false) { if (!IsWaiting && !Global.Settings.StopWhenExited && !forceExit) { MessageBoxX.Show(i18N.Translate("Please press Stop button first")); NotifyIcon_MouseDoubleClick(null, null); return; } Hide(); NotifyIcon.Visible = false; if (!IsWaiting) { ControlFun(); } Configuration.Save(); State = State.Terminating; }
private void ImportServersFromClipboardToolStripMenuItem_Click(object sender, EventArgs e) { var texts = Clipboard.GetText(); if (!string.IsNullOrWhiteSpace(texts)) { var result = ShareLink.Parse(texts); if (result != null) { Global.Settings.Server.AddRange(result); } else { MessageBoxX.Show(i18N.Translate("Import servers error!"), info: false); } InitServer(); Configuration.Save(); } }
private void ControlButton_Click(object sender, EventArgs e) { Utils.Utils.ComponentIterator(this, component => Utils.Utils.ChangeControlForeColor(component, Color.Black)); var flag = true; foreach (var pair in _checkActions.Where(pair => !pair.Value.Invoke(pair.Key.Text))) { Utils.Utils.ChangeControlForeColor(pair.Key, Color.Red); flag = false; } if (!flag) { return; } foreach (var pair in _saveActions) { switch (pair.Key) { case CheckBox c: pair.Value.Invoke(c.Checked); break; default: pair.Value.Invoke(pair.Key.Text); break; } } if (Global.Settings.Server.IndexOf(Server) == -1) { Global.Settings.Server.Add(Server); } MessageBoxX.Show(i18N.Translate("Saved")); Close(); }
private void EditServerPictureBox_Click(object sender, EventArgs e) { SaveConfigs(); // 当前ServerComboBox中至少有一项 if (ServerComboBox.SelectedIndex != -1) { switch (Global.Settings.Server[ServerComboBox.SelectedIndex].Type) { case "Socks5": new Socks5(ServerComboBox.SelectedIndex).Show(); break; case "SS": new Shadowsocks(ServerComboBox.SelectedIndex).Show(); break; case "SSR": new ShadowsocksR(ServerComboBox.SelectedIndex).Show(); break; case "VMess": new VMess(ServerComboBox.SelectedIndex).Show(); break; case "Trojan": new Trojan(ServerComboBox.SelectedIndex).Show(); break; default: return; } Hide(); } else { MessageBoxX.Show(i18N.Translate("Please select a server first")); } }
private void EditModePictureBox_Click(object sender, EventArgs e) { // 当前ModeComboBox中至少有一项 if (ModeComboBox.Items.Count > 0 && ModeComboBox.SelectedIndex != -1) { SaveConfigs(); var selectedMode = (Models.Mode)ModeComboBox.SelectedItem; // 只允许修改进程加速的模式 if (selectedMode.Type == 0) { //Process.Start(Environment.CurrentDirectory + "\\mode\\" + selectedMode.FileName + ".txt"); var process = new Process(selectedMode); process.Text = "Edit Process Mode"; process.Show(); Hide(); } } else { MessageBoxX.Show(i18N.Translate("Please select a mode first")); } }
private void UninstallServiceToolStripMenuItem_Click(object sender, EventArgs e) { Enabled = false; StatusText(i18N.Translate("Uninstalling NF Service")); Task.Run(() => { try { if (NFController.UninstallDriver()) { StatusText(i18N.Translate("Service has been uninstalled")); } } catch (Exception e) { MessageBoxX.Show(e.ToString(), LogLevel.ERROR); throw; } Enabled = true; }); }
private void ImportServersFromClipboardToolStripMenuItem_Click(object sender, EventArgs e) { var texts = Clipboard.GetText(); if (!string.IsNullOrWhiteSpace(texts)) { var result = ShareLink.Parse(texts); if (result != null) { foreach (var server in result) { Global.Settings.Server.Add(server); } } else { MessageBoxX.Show(i18N.Translate("Import servers error!"), LogLevel.ERROR); } Configuration.Save(); } }
private void UninstallServiceToolStripMenuItem_Click(object sender, EventArgs e) { Enabled = false; StatusText(i18N.Translate("Uninstalling Service")); Task.Run(() => { try { if (new NFController().UninstallDriver()) { MessageBoxX.Show(i18N.Translate("Service has been uninstalled"), owner: this); } } catch (Exception e) { MessageBox.Show(i18N.Translate("Error", e.Message)); Console.WriteLine(e); throw; } Enabled = true; }); }
private void EditServerPictureBox_Click(object sender, EventArgs e) { // 当前ServerComboBox中至少有一项 if (ServerComboBox.SelectedIndex == -1) { MessageBoxX.Show(i18N.Translate("Please select a server first")); return; } Form server = Global.Settings.Server[ServerComboBox.SelectedIndex].Type switch { "Socks5" => new Socks5(Global.Settings.Server[ServerComboBox.SelectedIndex]), "SS" => new Shadowsocks(Global.Settings.Server[ServerComboBox.SelectedIndex]), "SSR" => new ShadowsocksR(Global.Settings.Server[ServerComboBox.SelectedIndex]), "VMess" => new VMess(Global.Settings.Server[ServerComboBox.SelectedIndex]), "Trojan" => new Trojan(Global.Settings.Server[ServerComboBox.SelectedIndex]), _ => null }; Hide(); server?.ShowDialog(); Configuration.Save(); Show(); }
private void Exit(bool forceExit = false) { if (State != State.Waiting && State != State.Stopped && !Global.Settings.StopWhenExited && !forceExit) { MessageBoxX.Show(i18N.Translate("Please press Stop button first")); Visible = true; ShowInTaskbar = true; // 显示在系统任务栏 WindowState = FormWindowState.Normal; // 还原窗体 NotifyIcon.Visible = true; // 托盘图标隐藏 return; } Hide(); NotifyIcon.Visible = false; if (State != State.Waiting && State != State.Stopped) { // 已启动 ControlFun(); } Task.Run(() => { for (var i = 0; i < 16; i++) { if (State == State.Waiting || State == State.Stopped) { break; } Thread.Sleep(250); } SaveConfigs(); State = State.Terminating; }); }
private void DeleteModePictureBox_Click(object sender, EventArgs e) { // 当前ModeComboBox中至少有一项 if (ModeComboBox.Items.Count > 0 && ModeComboBox.SelectedIndex != -1) { var selectedMode = (Models.Mode)ModeComboBox.SelectedItem; //删除模式文件 selectedMode.DeleteFile("mode"); ModeComboBox.Items.Clear(); Global.ModeFiles.Remove(selectedMode); var array = Global.ModeFiles.ToArray(); Array.Sort(array, (a, b) => string.Compare(a.Remark, b.Remark, StringComparison.Ordinal)); ModeComboBox.Items.AddRange(array); SelectLastMode(); Configuration.Save(); } else { MessageBoxX.Show(i18N.Translate("Please select a mode first")); } }
private async void NewVersionLabel_Click(object sender, EventArgs e) { if (!_updater.LatestVersionDownloadUrl.Contains("Netch")) { Utils.Utils.Open(_updater.LatestVersionUrl); return; } if (MessageBoxX.Show(i18N.Translate("Download and install now?"), confirm: true) != DialogResult.OK) { return; } NotifyTip(i18N.Translate("Start downloading new version")); var tagPage = await WebUtil.DownloadStringAsync(WebUtil.CreateRequest(_updater.LatestVersionUrl)); var match = Regex.Match(tagPage, @"<td .*>(?<sha256>.*)</td>", RegexOptions.Singleline); // TODO Replace with regex get basename and sha256 var fileName = Path.GetFileName(new Uri(_updater.LatestVersionDownloadUrl).LocalPath); fileName = fileName.Insert(fileName.LastIndexOf('.'), _updater.LatestVersionNumber); var fileFullPath = Path.Combine(Global.NetchDir, "data", fileName); var sha256 = match.Groups["sha256"].Value; try { if (File.Exists(fileFullPath)) { if (Utils.Utils.SHA256CheckSum(fileFullPath) == sha256) { RunUpdater(); return; } File.Delete(fileFullPath); } // TODO Replace "New Version Found" to Progress bar await WebUtil.DownloadFileAsync(WebUtil.CreateRequest(_updater.LatestVersionDownloadUrl), fileFullPath); if (Utils.Utils.SHA256CheckSum(fileFullPath) != sha256) { MessageBoxX.Show("The downloaded file has the wrong hash"); return; } RunUpdater(); } catch (Exception exception) { NotifyTip($"{i18N.Translate("Download update failed")}\n{exception.Message}"); Logging.Error($"下载更新失败 {exception}"); } void RunUpdater() { // if debugging process stopped, debugger will kill child processes!!!! // 调试进程结束,调试器将会杀死子进程 // uncomment if(!Debugger.isAttach) block in NetchUpdater Project's main() method and attach to NetchUpdater process to debug // 在 NetchUpdater 项目的 main() 方法中取消注释 if(!Debugger.isAttach)块,并附加到 NetchUpdater 进程进行调试 Process.Start(new ProcessStartInfo { FileName = Path.Combine(Global.NetchDir, "NetchUpdater.exe"), Arguments = $"{Global.Settings.UDPSocketPort} \"{fileFullPath}\" \"{Global.NetchDir}\"" }); } }
public void ControlFun() { SaveConfigs(); if (State == State.Waiting || State == State.Stopped) { // 服务器、模式 需选择 if (ServerComboBox.SelectedIndex == -1) { MessageBoxX.Show(i18N.Translate("Please select a server first")); return; } if (ModeComboBox.SelectedIndex == -1) { MessageBoxX.Show(i18N.Translate("Please select an mode first")); return; } //MenuStrip.Enabled = ConfigurationGroupBox.Enabled = ControlButton.Enabled = SettingsButton.Enabled = false; UpdateStatus(State.Starting); Firewall.AddNetchFwRules(); Task.Run(() => { var server = ServerComboBox.SelectedItem as Models.Server; var mode = ModeComboBox.SelectedItem as Models.Mode; MainController ??= new MainController(); var startResult = MainController.Start(server, mode); if (startResult) { Task.Run(() => { UpdateStatus(State.Started); StatusText(i18N.Translate(StateExtension.GetStatusString(State)) + PortText(server.Type, mode.Type)); LastUploadBandwidth = 0; //LastDownloadBandwidth = 0; //UploadSpeedLabel.Text = "↑: 0 KB/s"; DownloadSpeedLabel.Text = "↑↓: 0 KB/s"; UsedBandwidthLabel.Text = $"{i18N.Translate("Used",": ")}0 KB"; UsedBandwidthLabel.Visible = UploadSpeedLabel.Visible = DownloadSpeedLabel.Visible = true; UploadSpeedLabel.Visible = false; Bandwidth.NetTraffic(server, mode, MainController); }); // 如果勾选启动后最小化 if (Global.Settings.MinimizeWhenStarted) { WindowState = FormWindowState.Minimized; NotifyIcon.Visible = true; if (IsFirstOpened) { // 显示提示语 NotifyIcon.ShowBalloonTip(5, UpdateChecker.Name, i18N.Translate( "Netch is now minimized to the notification bar, double click this icon to restore."), ToolTipIcon.Info); IsFirstOpened = false; } Hide(); } if (Global.Settings.StartedTcping) { // 自动检测延迟 Task.Run(() => { while (true) { if (State == State.Started) { server.Test(); // 重载服务器列表 InitServer(); Thread.Sleep(Global.Settings.StartedTcping_Interval * 1000); } else { break; } } }); } } else { UpdateStatus(State.Stopped); StatusText(i18N.Translate("Start failed")); } }); } else { // 停止 UpdateStatus(State.Stopping); MainController.Stop(); UpdateStatus(State.Stopped); Task.Run(() => { TestServer(); }); } }