diff --git a/Netch/Controllers/MainController.cs b/Netch/Controllers/MainController.cs index 34a30074..49b42151 100644 --- a/Netch/Controllers/MainController.cs +++ b/Netch/Controllers/MainController.cs @@ -38,6 +38,7 @@ namespace Netch.Controllers /// 是否启动成功 public bool Start(Server server, Mode mode) { + Logging.Info($"启动主控制器: {server.Type} [{mode.Type}]{mode.Remark}"); FlushDNSResolverCache(); var result = false; @@ -90,7 +91,6 @@ namespace Netch.Controllers if (result) { - Logging.Info("加密代理已启动"); switch (mode.Type) { case 0: // 进程代理模式 @@ -136,7 +136,11 @@ namespace Netch.Controllers } } - if (!result) Stop(); + if (!result) + { + Logging.Error("主控制器启动失败"); + Stop(); + } return result; } diff --git a/Netch/Controllers/Mode/NFController.cs b/Netch/Controllers/Mode/NFController.cs index 7d4bcfd9..56663cd1 100644 --- a/Netch/Controllers/Mode/NFController.cs +++ b/Netch/Controllers/Mode/NFController.cs @@ -175,7 +175,7 @@ namespace Netch.Controllers public static bool UninstallDriver() { Global.MainForm.StatusText(i18N.Translate("Uninstalling NF Service")); - Logging.Info("卸载NF驱动"); + Logging.Info("卸载 NF 驱动"); try { if (NFService.Status == ServiceControllerStatus.Running) @@ -211,7 +211,7 @@ namespace Netch.Controllers /// 驱动是否安装成功 public static bool InstallDriver() { - Logging.Info("安装NF驱动"); + Logging.Info("安装 NF 驱动"); try { File.Copy(BinDriver, SystemDriver); @@ -227,7 +227,7 @@ namespace Netch.Controllers var result = NFAPI.nf_registerDriver("netfilter2"); if (result == NF_STATUS.NF_STATUS_SUCCESS) { - Logging.Info($"驱动安装成功,当前驱动版本:{DriverVersion(SystemDriver)}"); + Logging.Info($"驱动安装成功"); } else { diff --git a/Netch/Controllers/Mode/TUNTAPController.cs b/Netch/Controllers/Mode/TUNTAPController.cs index 7c570463..ba9ccd0c 100644 --- a/Netch/Controllers/Mode/TUNTAPController.cs +++ b/Netch/Controllers/Mode/TUNTAPController.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.IO; +using System.Linq; using System.Net; using System.Net.NetworkInformation; using System.Net.Sockets; @@ -38,7 +38,7 @@ namespace Netch.Controllers Name = "Tap"; MainFile = "tun2socks.exe"; StartedKeywords("Running"); - StoppedKeywords("failed","invalid vconfig file"); + StoppedKeywords("failed", "invalid vconfig file"); } /// @@ -56,154 +56,113 @@ namespace Netch.Controllers } // 搜索出口 - return SearchOutbounds(); + return SearchAdapters(); } + private readonly List _directIPs = new List(); + private readonly List _proxyIPs = new List(); + /// /// 设置绕行规则 + /// 是否设置成功 /// - private bool SetupBypass() + private bool SetupRouteTable() { + Logging.Info("收集路由表规则"); Global.MainForm.StatusText(i18N.Translate("SetupBypass")); - Logging.Info("设置绕行规则 → 设置让服务器 IP 走直连"); - // 让服务器 IP 走直连 - foreach (var address in _serverAddresses) - if (!IPAddress.IsLoopback(address)) - NativeMethods.CreateRoute(address.ToString(), 32, Global.Adapter.Gateway.ToString(), Global.Adapter.Index); - // 处理模式的绕过中国 + Logging.Info("绕行 → 全局绕过 IP"); + _directIPs.AddRange(Global.Settings.BypassIPs.Select(IPNetwork.Parse)); + + Logging.Info("绕行 → 服务器 IP"); + _directIPs.AddRange(_serverAddresses.Where(address => !IPAddress.IsLoopback(address)).Select(address => IPNetwork.Parse(address.ToString(), 32))); + if (_savedMode.BypassChina) { - Logging.Info("设置绕行规则 → 处理模式的绕过中国"); - using (var sr = new StringReader(Encoding.UTF8.GetString(Resources.CNIP))) - { - string text; - - while ((text = sr.ReadLine()) != null) - { - var info = text.Split('/'); - - NativeMethods.CreateRoute(info[0], int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index); - } - } + Logging.Info("绕行 → 中国 IP"); + _directIPs.AddRange(Encoding.UTF8.GetString(Resources.CNIP).Split('\n').Select(IPNetwork.Parse)); } - Logging.Info("设置绕行规则 → 处理全局绕过 IP"); - // 处理全局绕过 IP - foreach (var ip in Global.Settings.BypassIPs) + Logging.Info("绕行 → 局域网 IP"); + _directIPs.AddRange(_bypassLanIPs.Select(IPNetwork.Parse)); + + switch (_savedMode.Type) { - var info = ip.Split('/'); - var address = IPAddress.Parse(info[0]); + case 1: + // 代理规则 + Logging.Info("代理 → 规则 IP"); + _proxyIPs.AddRange(_savedMode.Rule.Select(IPNetwork.Parse)); - if (!IPAddress.IsLoopback(address)) NativeMethods.CreateRoute(address.ToString(), int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index); - } - - Logging.Info("设置绕行规则 → 处理绕过局域网 IP"); - // 处理绕过局域网 IP - foreach (var ip in _bypassLanIPs) - { - var info = ip.Split('/'); - var address = IPAddress.Parse(info[0]); - - if (!IPAddress.IsLoopback(address)) NativeMethods.CreateRoute(address.ToString(), int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index); - } - - if (_savedMode.Type == 2) // 处理仅规则内走直连 - { - Logging.Info("设置绕行规则 → 处理仅规则内走直连"); - // 将 TUN/TAP 网卡权重放到最高 - var instance = new Process - { - StartInfo = - { - FileName = "netsh", - Arguments = string.Format("interface ip set interface {0} metric=0", Global.TUNTAP.Index), - WindowStyle = ProcessWindowStyle.Hidden, - UseShellExecute = true, - CreateNoWindow = true - } - }; - instance.Start(); - - Logging.Info("设置绕行规则 → 创建默认路由"); - // 创建默认路由 - if (!NativeMethods.CreateRoute("0.0.0.0", 0, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index, 10)) - { - State = State.Stopped; - - foreach (var address in _serverAddresses) NativeMethods.DeleteRoute(address.ToString(), 32, Global.Adapter.Gateway.ToString(), Global.Adapter.Index); - - return false; - } - - Logging.Info("设置绕行规则 → 创建规则路由"); - // 创建规则路由 - foreach (var ip in _savedMode.Rule) - { - var info = ip.Split('/'); - - if (info.Length == 2) - if (int.TryParse(info[1], out var prefix)) - NativeMethods.CreateRoute(info[0], prefix, Global.Adapter.Gateway.ToString(), Global.Adapter.Index); - } - } - else if (_savedMode.Type == 1) // 处理仅规则内走代理 - { - Logging.Info("设置绕行规则->处理仅规则内走代理"); - foreach (var ip in _savedMode.Rule) - { - var info = ip.Split('/'); - - if (info.Length == 2) - if (int.TryParse(info[1], out var prefix)) - NativeMethods.CreateRoute(info[0], prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index); - } - - //处理 NAT 类型检测,由于协议的原因,无法仅通过域名确定需要代理的 IP,自己记录解析了返回的 IP,仅支持默认检测服务器 - if (Global.Settings.STUN_Server == "stun.stunprotocol.org") - try - { - var nttAddress = Dns.GetHostAddresses(Global.Settings.STUN_Server)[0]; - if (int.TryParse("32", out var prefix)) NativeMethods.CreateRoute(nttAddress.ToString(), prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index); - - var nttrAddress = Dns.GetHostAddresses("stunresponse.coldthunder11.com")[0]; - if (int.TryParse("32", out var prefixr)) NativeMethods.CreateRoute(nttrAddress.ToString(), prefixr, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index); - } - catch - { - Logging.Info("NAT 类型测试域名解析失败,将不会被添加到代理列表"); - } - - //处理DNS代理 - if (Global.Settings.TUNTAP.ProxyDNS) - { - Logging.Info("设置绕行规则 → 处理自定义 DNS 代理"); - if (Global.Settings.TUNTAP.UseCustomDNS) - { - var dns = string.Empty; - foreach (var value in Global.Settings.TUNTAP.DNS) + //处理 NAT 类型检测,由于协议的原因,无法仅通过域名确定需要代理的 IP,自己记录解析了返回的 IP,仅支持默认检测服务器 + if (Global.Settings.STUN_Server == "stun.stunprotocol.org") + try { - dns += value; - dns += ','; + Logging.Info("代理 → STUN 服务器 IP"); + _proxyIPs.AddRange(new[] + { + Dns.GetHostAddresses(Global.Settings.STUN_Server)[0], + Dns.GetHostAddresses("stunresponse.coldthunder11.com")[0] + }.Select(ip => IPNetwork.Parse(ip.ToString(), 32))); + } + catch + { + Logging.Info("NAT 类型测试域名解析失败,将不会被添加到代理列表"); } - dns = dns.Trim(); - dns = dns.Substring(0, dns.Length - 1); - if (int.TryParse("32", out var prefix)) NativeMethods.CreateRoute(dns, prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index); - } - else + if (Global.Settings.TUNTAP.ProxyDNS) { - if (int.TryParse("32", out var prefix)) + Logging.Info("代理 → 自定义 DNS"); + if (Global.Settings.TUNTAP.UseCustomDNS) { - NativeMethods.CreateRoute("1.1.1.1", prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index); - NativeMethods.CreateRoute("8.8.8.8", prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index); - NativeMethods.CreateRoute("9.9.9.9", prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index); - NativeMethods.CreateRoute("185.222.222.222", prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index); + var dns = string.Empty; + foreach (var value in Global.Settings.TUNTAP.DNS) + { + dns += value; + dns += ','; + } + + dns = dns.Trim(); + dns = dns.Substring(0, dns.Length - 1); + RouteAction(Action.Create, dns, 32, RouteType.TUNTAP); + } + else + { + _proxyIPs.AddRange(new[] {"1.1.1.1", "8.8.8.8", "9.9.9.9", "185.222.222.222"}.Select(ip => IPNetwork.Parse(ip, 32))); } } - } + + break; + case 2: + // 绕过规则 + + // 将 TUN/TAP 网卡权重放到最高 + Process.Start(new ProcessStartInfo + { + FileName = "netsh", + Arguments = $"interface ip set interface {Global.TUNTAP.Index} metric=0", + WindowStyle = ProcessWindowStyle.Hidden, + UseShellExecute = true, + CreateNoWindow = true + } + ); + + Logging.Info("绕行 → 规则 IP"); + _directIPs.AddRange(_savedMode.Rule.Select(IPNetwork.Parse)); + + Logging.Info("代理 → 全局"); + if (!RouteAction(Action.Create, IPNetwork.Parse("0.0.0.0", 0), RouteType.TUNTAP)) + { + State = State.Stopped; + return false; + } + + break; } + Logging.Info("设置路由规则"); + RouteAction(Action.Create, _directIPs, RouteType.Gateway); + RouteAction(Action.Create, _proxyIPs, RouteType.TUNTAP); + return true; } @@ -211,100 +170,21 @@ namespace Netch.Controllers /// /// 清除绕行规则 /// - public bool ClearBypass() + private bool ClearBypass() { - if (_savedMode.Type == 2) + switch (_savedMode.Type) { - NativeMethods.DeleteRoute("0.0.0.0", 0, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index, 10); - - foreach (var ip in _savedMode.Rule) - { - var info = ip.Split('/'); - - if (info.Length == 2) - if (int.TryParse(info[1], out var prefix)) - NativeMethods.DeleteRoute(info[0], prefix, Global.Adapter.Gateway.ToString(), Global.Adapter.Index); - } - } - else if (_savedMode.Type == 1) - { - foreach (var ip in _savedMode.Rule) - { - var info = ip.Split('/'); - - if (info.Length == 2) - if (int.TryParse(info[1], out var prefix)) - NativeMethods.DeleteRoute(info[0], prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index); - } - - if (Global.Settings.STUN_Server == "stun.stunprotocol.org") - try - { - var nttAddress = Dns.GetHostAddresses(Global.Settings.STUN_Server)[0]; - if (int.TryParse("32", out var prefix)) NativeMethods.DeleteRoute(nttAddress.ToString(), prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index); - - var nttrAddress = Dns.GetHostAddresses("stunresponse.coldthunder11.com")[0]; - if (int.TryParse("32", out var prefixr)) NativeMethods.DeleteRoute(nttrAddress.ToString(), prefixr, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index); - } - catch - { - } - - if (Global.Settings.TUNTAP.ProxyDNS) - { - if (Global.Settings.TUNTAP.UseCustomDNS) - { - var dns = string.Empty; - foreach (var value in Global.Settings.TUNTAP.DNS) - { - dns += value; - dns += ','; - } - - dns = dns.Trim(); - dns = dns.Substring(0, dns.Length - 1); - if (int.TryParse("32", out var prefix)) NativeMethods.DeleteRoute(dns, prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index); - } - else - { - if (int.TryParse("32", out var prefix)) NativeMethods.DeleteRoute("1.1.1.1", prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index); - } - } + case 1: + break; + case 2: + RouteAction(Action.Delete, "0.0.0.0", 0, RouteType.TUNTAP, 10); + break; } - foreach (var ip in Global.Settings.BypassIPs) - { - var info = ip.Split('/'); - var address = IPAddress.Parse(info[0]); - - if (!IPAddress.IsLoopback(address)) NativeMethods.DeleteRoute(address.ToString(), int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index); - } - - foreach (var ip in _bypassLanIPs) - { - var info = ip.Split('/'); - var address = IPAddress.Parse(info[0]); - - if (!IPAddress.IsLoopback(address)) NativeMethods.DeleteRoute(address.ToString(), int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index); - } - - if (_savedMode.BypassChina) - using (var sr = new StringReader(Encoding.UTF8.GetString(Resources.CNIP))) - { - string text; - - while ((text = sr.ReadLine()) != null) - { - var info = text.Split('/'); - - NativeMethods.DeleteRoute(info[0], int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index); - } - } - - foreach (var address in _serverAddresses) - if (!IPAddress.IsLoopback(address)) - NativeMethods.DeleteRoute(address.ToString(), 32, Global.Adapter.Gateway.ToString(), Global.Adapter.Index); - + RouteAction(Action.Delete, _directIPs, RouteType.Gateway); + RouteAction(Action.Delete, _proxyIPs, RouteType.TUNTAP); + _directIPs.Clear(); + _proxyIPs.Clear(); return true; } @@ -317,14 +197,11 @@ namespace Netch.Controllers if (!Configure()) return false; - Logging.Info("设置绕行规则"); - SetupBypass(); - Logging.Info("设置绕行规则完毕"); + SetupRouteTable(); Instance = GetProcess(); var adapterName = TUNTAP.GetName(Global.TUNTAP.ComponentID); - Logging.Info($"tun2sock使用适配器:{adapterName}"); string dns; //V2ray使用Unbound本地DNS会导致查询异常缓慢故此V2ray不启动unbound而是使用自定义DNS @@ -372,8 +249,8 @@ namespace Netch.Controllers case State.Started: return true; case State.Stopped: - Stop(); - return false; + Stop(); + return false; } } @@ -395,74 +272,25 @@ namespace Netch.Controllers } /// - /// 搜索出口 + /// 搜索出口和TUNTAP适配器 /// - public static bool SearchOutbounds() + private static bool SearchAdapters() { - Logging.Info("正在搜索出口中"); - + NetworkInterface adapter; + Logging.Info("搜索适配器"); if (Win32Native.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse("114.114.114.114").GetAddressBytes(), 0), 0, out var pRoute) == 0) { Global.Adapter.Index = pRoute.dwForwardIfIndex; + adapter = NetworkInterface.GetAllNetworkInterfaces().First(_ => _.GetIPProperties().GetIPv4Properties().Index == Global.Adapter.Index); + Global.Adapter.Address = adapter.GetIPProperties().UnicastAddresses.First(ip => ip.Address.AddressFamily == AddressFamily.InterNetwork).Address; Global.Adapter.Gateway = new IPAddress(pRoute.dwForwardNextHop); - Logging.Info($"当前 网关 地址:{Global.Adapter.Gateway}"); + Logging.Info($"出口 IPv4 地址:{Global.Adapter.Address}"); + Logging.Info($"出口 网关 地址:{Global.Adapter.Gateway}"); + Logging.Info($"出口适配器:{adapter.Name} {adapter.Id} {adapter.Description}, index: {Global.Adapter.Index}"); } else { - Logging.Error("GetBestRoute 搜索失败"); - return false; - } - - Logging.Info($"搜索适配器index:{Global.Adapter.Index}"); - var AddressGot = false; - foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces()) - try - { - var adapterProperties = adapter.GetIPProperties(); - var p = adapterProperties.GetIPv4Properties(); - Logging.Info($"检测适配器:{adapter.Name} {adapter.Id} {adapter.Description}, index: {p.Index}"); - - // 通过索引查找对应适配器的 IPv4 地址 - if (p.Index == Global.Adapter.Index) - { - var AdapterIPs = string.Empty; - - foreach (var ip in adapterProperties.UnicastAddresses) - { - if (ip.Address.AddressFamily == AddressFamily.InterNetwork) - { - AddressGot = true; - Global.Adapter.Address = ip.Address; - Logging.Info($"当前出口 IPv4 地址:{Global.Adapter.Address}"); - break; - } - - AdapterIPs = $"{ip.Address} | "; - } - - if (!AddressGot) - { - if (AdapterIPs.Length > 3) - { - AdapterIPs = AdapterIPs.Substring(0, AdapterIPs.Length - 3); - Logging.Info($"所有出口地址:{AdapterIPs}"); - } - - Logging.Error("出口无 IPv4 地址,当前只支持 IPv4 地址"); - return false; - } - - break; - } - } - catch (Exception) - { - // ignored - } - - if (!AddressGot) - { - Logging.Error("无法找到当前使用适配器"); + Logging.Error("GetBestRoute 搜索失败(找不到出口适配器)"); return false; } @@ -470,11 +298,11 @@ namespace Netch.Controllers Global.TUNTAP.ComponentID = TUNTAP.GetComponentID(); if (string.IsNullOrEmpty(Global.TUNTAP.ComponentID)) { - Logging.Error("未找到可用 TUN/TAP 适配器"); + Logging.Error("未找到可用 TAP 适配器"); if (MessageBoxX.Show(i18N.Translate("TUN/TAP driver is not detected. Is it installed now?"), confirm: true) == DialogResult.OK) { Configuration.addtap(); - //给点时间,不然立马安装完毕就查找适配器可能会导致找不到适配器ID + // 给点时间,不然立马安装完毕就查找适配器可能会导致找不到适配器ID Thread.Sleep(1000); Global.TUNTAP.ComponentID = TUNTAP.GetComponentID(); } @@ -482,24 +310,62 @@ namespace Netch.Controllers { return false; } - - //MessageBoxX.Show(i18N.Translate("Please install TAP-Windows and create an TUN/TAP adapter manually")); - // return false; } - foreach (var adapter in NetworkInterface.GetAllNetworkInterfaces()) - if (adapter.Id == Global.TUNTAP.ComponentID) - { - Global.TUNTAP.Adapter = adapter; - Global.TUNTAP.Index = adapter.GetIPProperties().GetIPv4Properties().Index; + adapter = NetworkInterface.GetAllNetworkInterfaces().First(_ => _.Id == Global.TUNTAP.ComponentID); + Global.TUNTAP.Adapter = adapter; + Global.TUNTAP.Index = adapter.GetIPProperties().GetIPv4Properties().Index; + Logging.Info($"TAP 适配器:{adapter.Name} {adapter.Id} {adapter.Description}, index: {Global.TUNTAP.Index}"); + return true; + } - Logging.Info($"找到适配器TUN/TAP:{adapter.Id}"); - return true; - } + private enum RouteType + { + Gateway, + TUNTAP + } - Logging.Error("无法找到出口"); - return false; + private enum Action + { + Create, + Delete + } + + private static bool RouteAction(Action action, IEnumerable ipNetworks, RouteType routeType, int metric = 0) + { + return ipNetworks.All(address => RouteAction(action, address, routeType, metric)); + } + + private static bool RouteAction(Action action, string address, byte cidr, RouteType routeType, int metric = 0) + { + return RouteAction(action, IPNetwork.Parse(address, cidr), routeType, metric); + } + + private static bool RouteAction(Action action, IPNetwork ipNetwork, RouteType routeType, int metric = 0) + { + string gateway; + int index; + switch (routeType) + { + case RouteType.Gateway: + gateway = Global.Adapter.Gateway.ToString(); + index = Global.Adapter.Index; + break; + case RouteType.TUNTAP: + gateway = Global.Settings.TUNTAP.Gateway; + index = Global.TUNTAP.Index; + break; + default: + throw new ArgumentOutOfRangeException(nameof(routeType), routeType, null); + } + + return action switch + { + Action.Create => NativeMethods.CreateRoute(ipNetwork.Network.ToString(), ipNetwork.Cidr, gateway, index, metric), + Action.Delete => NativeMethods.DeleteRoute(ipNetwork.Network.ToString(), ipNetwork.Cidr, gateway, index, metric), + _ => throw new ArgumentOutOfRangeException(nameof(action), action, null) + }; } } } \ No newline at end of file diff --git a/Netch/Controllers/NTTController.cs b/Netch/Controllers/NTTController.cs index 6fd24209..4389e7e3 100644 --- a/Netch/Controllers/NTTController.cs +++ b/Netch/Controllers/NTTController.cs @@ -1,4 +1,5 @@ using System; +using System.ComponentModel; using System.Diagnostics; using Netch.Models; using Netch.Utils; @@ -43,7 +44,7 @@ namespace Netch.Controllers return (true, natType, localEnd, publicEnd); } - catch (Exception e) + catch (Win32Exception e) { Logging.Error("NTT 进程出错\n" + e); Stop(); diff --git a/Netch/Forms/MainForm.MenuStrip.cs b/Netch/Forms/MainForm.MenuStrip.cs index bb404e66..840694d5 100644 --- a/Netch/Forms/MainForm.MenuStrip.cs +++ b/Netch/Forms/MainForm.MenuStrip.cs @@ -1,7 +1,6 @@ using System; using System.Linq; using System.Net; -using System.ServiceProcess; using System.Threading.Tasks; using System.Windows.Forms; using Netch.Controllers; @@ -9,7 +8,6 @@ using Netch.Forms.Mode; using Netch.Forms.Server; using Netch.Models; using Netch.Utils; -using nfapinet; using Trojan = Netch.Forms.Server.Trojan; using VMess = Netch.Forms.Server.VMess; using WebClient = Netch.Override.WebClient; @@ -39,7 +37,7 @@ namespace Netch.Forms } else { - MessageBoxX.Show(i18N.Translate("Import servers error!"), info: false); + MessageBoxX.Show(i18N.Translate("Import servers error!"), LogLevel.ERROR); } InitServer(); @@ -246,8 +244,7 @@ namespace Netch.Forms } catch (Exception e) { - MessageBoxX.Show(e.ToString(),info:false); - Console.WriteLine(e); + MessageBoxX.Show(e.ToString(),LogLevel.ERROR); throw; } Enabled = true; @@ -290,7 +287,7 @@ namespace Netch.Forms private void OpenDirectoryToolStripMenuItem_Click(object sender, EventArgs e) { - Utils.Utils.OpenDir(@".\"); + Utils.Utils.Open(@".\"); } private void reinstallTapDriverToolStripMenuItem_Click(object sender, EventArgs e) diff --git a/Netch/Global.cs b/Netch/Global.cs index d4eba7cf..59029627 100644 --- a/Netch/Global.cs +++ b/Netch/Global.cs @@ -11,7 +11,7 @@ namespace Netch /// /// 换行 /// - public static string EOF = "\r\n"; + public const string EOF = "\r\n"; public static readonly string NetchDir = (AppDomain.CurrentDomain.BaseDirectory).TrimEnd(); diff --git a/Netch/Models/LogLevel.cs b/Netch/Models/LogLevel.cs new file mode 100644 index 00000000..760ce5df --- /dev/null +++ b/Netch/Models/LogLevel.cs @@ -0,0 +1,9 @@ +namespace Netch.Models +{ + public enum LogLevel + { + INFO, + WARNING, + ERROR + } +} \ No newline at end of file diff --git a/Netch/NativeMethods.cs b/Netch/NativeMethods.cs index e754fde9..2574e63d 100644 --- a/Netch/NativeMethods.cs +++ b/Netch/NativeMethods.cs @@ -8,25 +8,25 @@ namespace Netch /// 创建路由规则 /// /// 目标地址 - /// 掩码地址 + /// CIDR /// 网关地址 /// 适配器索引 /// 跃点数 /// 是否成功 [DllImport("bin\\NetchCore", CallingConvention = CallingConvention.Cdecl, EntryPoint = "CreateRoute")] - public static extern bool CreateRoute(string address, int netmask, string gateway, int index, int metric = 0); + public static extern bool CreateRoute(string address, int cidr, string gateway, int index, int metric = 0); /// /// 修改路由规则 /// /// 目标地址 - /// 掩码地址 + /// CIDR /// 网关地址 /// 适配器索引 /// 跃点数 /// 是否成功 [DllImport("bin\\NetchCore", CallingConvention = CallingConvention.Cdecl, EntryPoint = "ChangeRoute")] - public static extern bool ChangeRoute(string address, int netmask, string gateway, int index, int metric = 0); + public static extern bool ChangeRoute(string address, int cidr, string gateway, int index, int metric = 0); /// /// 删除路由规则 @@ -38,7 +38,7 @@ namespace Netch /// 跃点数 /// 是否成功 [DllImport("bin\\NetchCore", CallingConvention = CallingConvention.Cdecl, EntryPoint = "DeleteRoute")] - public static extern bool DeleteRoute(string address, int netmask, string gateway, int index, int metric = 0); + public static extern bool DeleteRoute(string address, int cidr, string gateway, int index, int metric = 0); /// /// 设置直连 diff --git a/Netch/Netch.cs b/Netch/Netch.cs index 556f2e6f..cec72d8e 100644 --- a/Netch/Netch.cs +++ b/Netch/Netch.cs @@ -58,8 +58,8 @@ namespace Netch // 记录当前系统语言 Logging.Info($"当前语言:{Global.Settings.Language}"); - Logging.Info($"版本:{UpdateChecker.Owner}/{UpdateChecker.Repo} {UpdateChecker.Version}"); - Logging.Info($"主程序创建日期:{File.GetCreationTime(Global.NetchDir + "\\Netch.exe"):yyyy-M-d HH:mm}"); + Logging.Info($"版本: {UpdateChecker.Owner}/{UpdateChecker.Repo}@{UpdateChecker.Version}"); + Logging.Info($"主程序创建日期: {File.GetCreationTime(Global.NetchDir + "\\Netch.exe"):yyyy-M-d HH:mm}"); // 检查是否已经运行 if (!mutex.WaitOne(0, false)) @@ -85,7 +85,9 @@ namespace Netch { if (!e.Exception.ToString().Contains("ComboBox")) { - MessageBox.Show(e.Exception.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + Logging.Error("错误\n" + e); + Utils.Utils.Open(Logging.LogFile); + // MessageBox.Show(e.Exception.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } //Application.Exit(); } diff --git a/Netch/Netch.csproj b/Netch/Netch.csproj index 23ffabe8..7416ff3b 100644 --- a/Netch/Netch.csproj +++ b/Netch/Netch.csproj @@ -58,6 +58,7 @@ + diff --git a/Netch/Utils/Logging.cs b/Netch/Utils/Logging.cs index 4b293f21..1135d479 100644 --- a/Netch/Utils/Logging.cs +++ b/Netch/Utils/Logging.cs @@ -1,11 +1,12 @@ using System; using System.IO; +using Netch.Models; namespace Netch.Utils { - public static class Logging + public static partial class Logging { - private const string LogFile = "logging\\application.log"; + public const string LogFile = "logging\\application.log"; /// /// 信息 @@ -13,7 +14,7 @@ namespace Netch.Utils /// 内容 public static void Info(string text) { - File.AppendAllText(LogFile, $@"[{DateTime.Now}][INFO] {text}{Global.EOF}"); + Write(text, LogLevel.INFO); } /// @@ -22,7 +23,7 @@ namespace Netch.Utils /// 内容 public static void Warning(string text) { - File.AppendAllText(LogFile, $@"[{DateTime.Now}][WARNING] {text}{Global.EOF}"); + Write(text, LogLevel.WARNING); } /// @@ -31,7 +32,12 @@ namespace Netch.Utils /// 内容 public static void Error(string text) { - File.AppendAllText(LogFile, $@"[{DateTime.Now}][ERROR] {text}{Global.EOF}"); + Write(text, LogLevel.ERROR); + } + + private static void Write(string text, LogLevel logLevel) + { + File.AppendAllText(LogFile, $@"[{DateTime.Now}][{logLevel.ToString()}] {text}{Global.EOF}"); } } } \ No newline at end of file diff --git a/Netch/Utils/MessageBoxX.cs b/Netch/Utils/MessageBoxX.cs index 4be0ab1e..1f096313 100644 --- a/Netch/Utils/MessageBoxX.cs +++ b/Netch/Utils/MessageBoxX.cs @@ -1,4 +1,6 @@ -using System.Windows.Forms; +using System; +using System.Windows.Forms; +using Netch.Models; namespace Netch.Utils { @@ -8,17 +10,35 @@ namespace Netch.Utils /// /// 内容 /// 自定义标题 - /// 弹窗等级 (标题, 图标) + /// 弹窗等级 (标题, 图标) /// 需要确认 /// 阻止 owner Focus() 直到 Messageox 被关闭 - public static DialogResult Show(string text, string title = "", bool info = true, bool confirm = false,IWin32Window owner = null) + public static DialogResult Show(string text, LogLevel level = LogLevel.INFO, string title = "", bool confirm = false, IWin32Window owner = null) { + MessageBoxIcon msgIcon; + if (string.IsNullOrWhiteSpace(title)) + title = level switch + { + LogLevel.INFO => "Information", + LogLevel.WARNING => "Warning", + LogLevel.ERROR => "Error", + _ => throw new ArgumentOutOfRangeException(nameof(level), level, null) + }; + + msgIcon = level switch + { + LogLevel.INFO => MessageBoxIcon.Information, + LogLevel.WARNING => MessageBoxIcon.Warning, + LogLevel.ERROR => MessageBoxIcon.Exclamation, + _ => throw new ArgumentOutOfRangeException(nameof(level), level, null) + }; + return MessageBox.Show( owner: owner, text: text, - caption: i18N.Translate(string.IsNullOrWhiteSpace(title) ? (info ? "Information" : "Error") : title), + caption: i18N.Translate(title), buttons: confirm ? MessageBoxButtons.OKCancel : MessageBoxButtons.OK, - icon: info ? MessageBoxIcon.Information : MessageBoxIcon.Exclamation); + icon: msgIcon); } } } \ No newline at end of file diff --git a/Netch/Utils/Utils.cs b/Netch/Utils/Utils.cs index 566d398b..c8dcce63 100644 --- a/Netch/Utils/Utils.cs +++ b/Netch/Utils/Utils.cs @@ -11,17 +11,16 @@ namespace Netch.Utils { public static class Utils { - public static bool OpenUrl(string path) + public static bool Open(string path) { try { - new Process + Process.Start(new ProcessStartInfo() { - StartInfo = new ProcessStartInfo(path) - { - UseShellExecute = true - } - }.Start(); + FileName = "explorer.exe", + Arguments = path, + UseShellExecute = true + }); return true; } catch @@ -30,23 +29,6 @@ namespace Netch.Utils } } - public static bool OpenDir(string dir) - { - if (Directory.Exists(dir)) - { - try - { - return OpenUrl(dir); - } - catch - { - // ignored - } - } - - return false; - } - public static async Task TCPingAsync(IPAddress ip, int port, int timeout = 1000, CancellationToken ct = default) { using var client = new TcpClient(ip.AddressFamily);