diff --git a/Netch/Controllers/Mode/TUNTAPController.cs b/Netch/Controllers/Mode/TUNTAPController.cs index bd966693..a8ec092a 100644 --- a/Netch/Controllers/Mode/TUNTAPController.cs +++ b/Netch/Controllers/Mode/TUNTAPController.cs @@ -64,8 +64,8 @@ namespace Netch.Controllers /// /// 设置绕行规则 - /// 是否设置成功 /// + /// 是否设置成功 private bool SetupRouteTable() { Logging.Info("收集路由表规则"); @@ -276,63 +276,88 @@ namespace Netch.Controllers /// private static bool SearchAdapters() { - 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; - Logging.Info($"出口 网关 地址:{Global.Adapter.Gateway}"); - try - { - adapter = NetworkInterface.GetAllNetworkInterfaces().First(_ => _.GetIPProperties().GetIPv4Properties().Index == Global.Adapter.Index); - } - catch (InvalidOperationException) - { - Logging.Error("找不到出口适配器"); - return false; - } - - Global.Adapter.Address = adapter.GetIPProperties().UnicastAddresses.First(ip => ip.Address.AddressFamily == AddressFamily.InterNetwork).Address; - Global.Adapter.Gateway = new IPAddress(pRoute.dwForwardNextHop); - Logging.Info($"出口 IPv4 地址:{Global.Adapter.Address}"); - Logging.Info($"出口适配器:{adapter.Name} {adapter.Id} {adapter.Description}, index: {Global.Adapter.Index}"); - } - else + // 寻找出口适配器 + if (Win32Native.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse("114.114.114.114").GetAddressBytes(), 0), 0, out var pRoute) != 0) { Logging.Error("GetBestRoute 搜索失败(找不到出口适配器)"); return false; } + Global.Adapter.Index = pRoute.dwForwardIfIndex; + // 搜索 TUN/TAP 适配器的索引 - Global.TUNTAP.ComponentID = TUNTAP.GetComponentID(); - if (string.IsNullOrEmpty(Global.TUNTAP.ComponentID)) + if (string.IsNullOrEmpty(Global.TUNTAP.ComponentID = TUNTAP.GetComponentID())) { - Logging.Error("找不到 TAP 适配器"); + Logging.Info("找不到 TAP 适配器"); if (MessageBoxX.Show(i18N.Translate("TUN/TAP driver is not detected. Is it installed now?"), confirm: true) == DialogResult.OK) { Configuration.addtap(); // 给点时间,不然立马安装完毕就查找适配器可能会导致找不到适配器ID Thread.Sleep(1000); - Global.TUNTAP.ComponentID = TUNTAP.GetComponentID(); + if (string.IsNullOrEmpty(Global.TUNTAP.ComponentID = TUNTAP.GetComponentID())) + { + Logging.Error("找不到 TAP 适配器,驱动可能安装失败"); + return false; + } } else { - Logging.Info("拒绝安装 TAP 适配器 "); + Logging.Info("取消安装 TAP 驱动 "); return false; } } try { - 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}"); + try + { + var 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($"出口 IPv4 地址:{Global.Adapter.Address}"); + Logging.Info($"出口 网关 地址:{Global.Adapter.Gateway}"); + Logging.Info($"出口适配器:{adapter.Name} {adapter.Id} {adapter.Description}, index: {Global.Adapter.Index}"); + // Ex NetworkInformationException: 此接口不支持 IPv4 协议。 + + // Ex NetworkInformationException: Windows 系统函数调用失败。 + // Ex System.ArgumentNullException: source 或 predicate 为 null。 + } + catch (Exception e) + { + if (e is InvalidOperationException) + Logging.Error($"找不到网络接口索引为 {Global.Adapter.Index} 的出口适配器"); + throw; + } + + try + { + var 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}"); + } + catch (Exception e) + { + if (e is InvalidOperationException) + Logging.Error($"找不到标识符为 {Global.TUNTAP.ComponentID} 的 TAP 适配器"); + throw; + } + return true; } catch (InvalidOperationException) { - Logging.Error("没有找到 TAP 适配器"); + // 理论上如果得到了网络接口的索引/网络适配器的标识符不会找不到网卡 + // 只是异常处理 + Logging.Info("所有适配器:\n" + + NetworkInterface.GetAllNetworkInterfaces().Aggregate(string.Empty, (current, adapter) + => current + $"{adapter.Name} {adapter.Id} {adapter.Description}, index: {Global.TUNTAP.Index}{Global.EOF}")); + return false; + } + catch (NetworkInformationException e) + { + if (e.ErrorCode == 10043) + MessageBoxX.Show("适配器未开启IPv4协议", LogLevel.ERROR, owner: Global.MainForm); return false; } } diff --git a/Netch/Forms/MainForm.Control.cs b/Netch/Forms/MainForm.Control.cs index 71c5f78d..95fbff3d 100644 --- a/Netch/Forms/MainForm.Control.cs +++ b/Netch/Forms/MainForm.Control.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -45,8 +46,22 @@ namespace Netch.Forms var server = ServerComboBox.SelectedItem as Models.Server; var mode = ModeComboBox.SelectedItem as Models.Mode; + var result = false; - if (_mainController.Start(server, mode)) + try + { + // TODO 完善控制器异常处理 + result = _mainController.Start(server, mode); + } + catch (Exception e) + { + if (e is DllNotFoundException || e is FileNotFoundException) + MessageBoxX.Show(e.Message + "\n\n" + i18N.Translate("Missing File or runtime components"), owner: this); + + Netch.Application_OnException(this, new ThreadExceptionEventArgs(e)); + } + + if (result) { Task.Run(() => { diff --git a/Netch/Forms/SettingForm.cs b/Netch/Forms/SettingForm.cs index e5c20d79..9fe5ea7f 100644 --- a/Netch/Forms/SettingForm.cs +++ b/Netch/Forms/SettingForm.cs @@ -363,7 +363,6 @@ namespace Netch.Forms /// /// /// - /// private bool CheckPortText(string portName, ref TextBox portTextBox, ref int originPort, PortType portType = PortType.Both) { // 端口检查 diff --git a/Netch/Netch.cs b/Netch/Netch.cs index cec72d8e..d4adc0fd 100644 --- a/Netch/Netch.cs +++ b/Netch/Netch.cs @@ -60,6 +60,7 @@ 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($"主程序 SHA256: {Utils.Utils.SHA256CheckSum(Application.ExecutablePath)}"); // 检查是否已经运行 if (!mutex.WaitOne(0, false)) @@ -83,13 +84,14 @@ namespace Netch public static void Application_OnException(object sender, ThreadExceptionEventArgs e) { - if (!e.Exception.ToString().Contains("ComboBox")) + Logging.Error(e.Exception.ToString()); + Utils.Utils.Open(Logging.LogFile); + /*if (!e.Exception.ToString().Contains("ComboBox")) { - Logging.Error("错误\n" + e); - Utils.Utils.Open(Logging.LogFile); - // MessageBox.Show(e.Exception.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } + MessageBox.Show(e.Exception.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + }*/ + //Application.Exit(); } } -} +} \ No newline at end of file diff --git a/Netch/Utils/Utils.cs b/Netch/Utils/Utils.cs index c8dcce63..b1b9e792 100644 --- a/Netch/Utils/Utils.cs +++ b/Netch/Utils/Utils.cs @@ -2,8 +2,11 @@ using System; using System.Diagnostics; using System.IO; +using System.Linq; using System.Net; using System.Net.Sockets; +using System.Security.Cryptography; +using System.Text; using System.Threading; using System.Threading.Tasks; @@ -45,6 +48,7 @@ namespace Netch.Utils var t = Convert.ToInt32(stopwatch.Elapsed.TotalMilliseconds); return t; } + return timeout; } @@ -54,6 +58,7 @@ namespace Netch.Utils { Hostname = Hostname.Split(':')[0]; } + string Country; try { @@ -81,7 +86,24 @@ namespace Netch.Utils { Country = "Unknown"; } + return Country == null ? "Unknown" : Country; } + + public static string SHA256CheckSum(string filePath) + { + try + { + var SHA256 = SHA256Managed.Create(); + var fileStream = File.OpenRead(filePath); + var s = string.Empty; + SHA256.ComputeHash(fileStream).Select(b => s+=b.ToString("x2")); + return s; + } + catch + { + return ""; + } + } } -} +} \ No newline at end of file