diff --git a/Netch/Controllers/DNSController.cs b/Netch/Controllers/DNSController.cs
index 03125753..53e3f40a 100644
--- a/Netch/Controllers/DNSController.cs
+++ b/Netch/Controllers/DNSController.cs
@@ -1,4 +1,5 @@
-using System.IO;
+using System;
+using System.IO;
using System.Runtime.InteropServices;
using System.Text;
@@ -8,11 +9,16 @@ namespace Netch.Controllers
{
public string Name { get; } = "DNS Service";
+ public void Stop()
+ {
+ aiodns_free();
+ }
+
///
/// 启动DNS服务
///
///
- public bool Start()
+ public void Start()
{
aiodns_dial((int) NameList.TYPE_REST, null);
aiodns_dial((int) NameList.TYPE_ADDR, Encoding.UTF8.GetBytes($"{Global.Settings.LocalAddress}:53"));
@@ -21,12 +27,8 @@ namespace Netch.Controllers
aiodns_dial((int) NameList.TYPE_ODNS, Encoding.UTF8.GetBytes($"{Global.Settings.AioDNS.OtherDNS}:53"));
aiodns_dial((int) NameList.TYPE_METH, Encoding.UTF8.GetBytes(Global.Settings.AioDNS.Protocol));
- return aiodns_init();
- }
-
- public void Stop()
- {
- aiodns_free();
+ if (aiodns_init())
+ throw new Exception("AioDNS start failed");
}
#region NativeMethods
@@ -40,7 +42,7 @@ namespace Netch.Controllers
[DllImport("aiodns.bin", CallingConvention = CallingConvention.Cdecl)]
public static extern void aiodns_free();
- enum NameList : int
+ private enum NameList
{
TYPE_REST,
TYPE_ADDR,
diff --git a/Netch/Controllers/Guard.cs b/Netch/Controllers/Guard.cs
index 71f23ac4..bae37183 100644
--- a/Netch/Controllers/Guard.cs
+++ b/Netch/Controllers/Guard.cs
@@ -14,6 +14,24 @@ namespace Netch.Controllers
{
public abstract class Guard
{
+ private static readonly Timer SaveBufferTimer = new(300) {AutoReset = true};
+
+ private readonly StringBuilder _logBuffer = new();
+
+ ///
+ /// 成功启动关键词
+ ///
+ protected readonly List StartedKeywords = new();
+
+ ///
+ /// 启动失败关键词
+ ///
+ protected readonly List StoppedKeywords = new();
+
+ ///
+ /// 日志文件(重定向输出文件)
+ ///
+ private string _logPath;
public virtual string Name { get; }
///
@@ -23,18 +41,6 @@ namespace Netch.Controllers
protected State State { get; set; } = State.Waiting;
- public abstract void Stop();
-
- ///
- /// 成功启动关键词
- ///
- protected readonly List StartedKeywords = new List();
-
- ///
- /// 启动失败关键词
- ///
- protected readonly List StoppedKeywords = new List();
-
///
/// 进程是否可以重定向输出
///
@@ -45,19 +51,14 @@ namespace Netch.Controllers
///
public Process Instance { get; private set; }
- ///
- /// 日志文件(重定向输出文件)
- ///
- private string _logPath;
-
- private readonly StringBuilder _logBuffer = new StringBuilder();
-
///
/// 程序输出的编码,
- /// 调用于基类的
+ /// 调用于基类的
///
protected Encoding InstanceOutputEncoding { get; set; } = Encoding.GetEncoding("gbk");
+ public abstract void Stop();
+
///
/// 停止进程
///
@@ -80,7 +81,7 @@ namespace Netch.Controllers
}
///
- /// 仅初始化 ,不设定事件处理方法
+ /// 仅初始化 ,不设定事件处理方法
///
///
protected virtual void InitInstance(string argument)
@@ -109,72 +110,59 @@ namespace Netch.Controllers
/// 主程序启动参数
/// 进程优先级
/// 是否成功启动
- protected bool StartInstanceAuto(string argument, ProcessPriorityClass priority = ProcessPriorityClass.Normal)
+ protected void StartInstanceAuto(string argument, ProcessPriorityClass priority = ProcessPriorityClass.Normal)
{
State = State.Starting;
- try
+ // 初始化程序
+ InitInstance(argument);
+ Instance.EnableRaisingEvents = true;
+ if (RedirectStd)
{
- // 初始化程序
- InitInstance(argument);
- Instance.EnableRaisingEvents = true;
- if (RedirectStd)
- {
- // 清理日志
- _logPath ??= Path.Combine(Global.NetchDir, $"logging\\{Name}.log");
- if (File.Exists(_logPath))
- File.Delete(_logPath);
+ // 清理日志
+ _logPath ??= Path.Combine(Global.NetchDir, $"logging\\{Name}.log");
+ if (File.Exists(_logPath))
+ File.Delete(_logPath);
- Instance.OutputDataReceived += OnOutputDataReceived;
- Instance.ErrorDataReceived += OnOutputDataReceived;
- }
-
- Instance.Exited += OnExited;
-
- // 启动程序
- Instance.Start();
- if (priority != ProcessPriorityClass.Normal)
- Instance.PriorityClass = priority;
- if (!RedirectStd) return true;
- // 启动日志重定向
- Instance.BeginOutputReadLine();
- Instance.BeginErrorReadLine();
- SaveBufferTimer.Elapsed += SaveBufferTimerEvent;
- SaveBufferTimer.Enabled = true;
- if (StartedKeywords.Count == 0) return true;
- // 等待启动
- for (var i = 0; i < 1000; i++)
- {
- Thread.Sleep(10);
- switch (State)
- {
- case State.Started:
- return true;
- case State.Stopped:
- Logging.Error($"{Name} 控制器启动失败");
- Stop();
- return false;
- }
- }
-
- Logging.Error($"{Name} 控制器启动超时");
- Stop();
- return false;
+ Instance.OutputDataReceived += OnOutputDataReceived;
+ Instance.ErrorDataReceived += OnOutputDataReceived;
}
- catch (Exception e)
+
+ Instance.Exited += OnExited;
+
+ // 启动程序
+ Instance.Start();
+ if (priority != ProcessPriorityClass.Normal)
+ Instance.PriorityClass = priority;
+ if (!RedirectStd) return;
+ // 启动日志重定向
+ Instance.BeginOutputReadLine();
+ Instance.BeginErrorReadLine();
+ SaveBufferTimer.Elapsed += SaveBufferTimerEvent;
+ SaveBufferTimer.Enabled = true;
+ if (StartedKeywords.Count == 0) return;
+ // 等待启动
+ for (var i = 0; i < 1000; i++)
{
- Logging.Error($"{Name} 控制器启动失败:\n {e}");
- return false;
+ Thread.Sleep(10);
+ switch (State)
+ {
+ case State.Started:
+ return;
+ case State.Stopped:
+ Stop();
+ Utils.Utils.Open(_logPath);
+ throw new Exception($"{Name} 控制器启动失败");
+ }
}
+
+ Stop();
+ throw new Exception($"{Name} 控制器启动超时");
}
- private static readonly Timer SaveBufferTimer = new Timer(300) {AutoReset = true};
-
private void OnExited(object sender, EventArgs e)
{
if (RedirectStd)
- {
SaveBufferTimer.Enabled = false;
- }
SaveBufferTimerEvent(null, null);
@@ -204,7 +192,7 @@ namespace Netch.Controllers
}
///
- /// 计时器存储日志
+ /// 计时器存储日志
///
///
///
diff --git a/Netch/Controllers/HTTPController.cs b/Netch/Controllers/HTTPController.cs
index 676ba190..36a9283e 100644
--- a/Netch/Controllers/HTTPController.cs
+++ b/Netch/Controllers/HTTPController.cs
@@ -1,10 +1,7 @@
using System;
-using System.Diagnostics;
using System.Threading.Tasks;
-using System.Windows.Forms;
using WindowsProxy;
using Microsoft.Win32;
-using Netch.Forms;
using Netch.Models;
using Netch.Servers.Socks5;
using Netch.Servers.Trojan;
@@ -27,42 +24,30 @@ namespace Netch.Controllers
///
/// 模式
/// 是否启动成功
- public bool Start(in Mode mode)
+ public void Start(in Mode mode)
{
RecordPrevious();
- try
- {
- if (pPrivoxyController.Start(MainController.Server, mode))
- Global.Job.AddProcess(pPrivoxyController.Instance);
+ pPrivoxyController.Start(MainController.Server);
+ Global.Job.AddProcess(pPrivoxyController.Instance);
- if (mode.Type == 3)
+ if (mode.Type == 3)
+ {
+ if (MainController.Server is Socks5 or Trojan && mode.BypassChina)
{
- if (MainController.Server is Socks5 or Trojan && mode.BypassChina)
+ //启动PAC服务器
+ PACServerHandle.InitPACServer("127.0.0.1");
+ }
+ else
+ {
+ using var service = new ProxyService
{
- //启动PAC服务器
- PACServerHandle.InitPACServer("127.0.0.1");
- }
- else
- {
- using var service = new ProxyService
- {
- Server = $"127.0.0.1:{Global.Settings.HTTPLocalPort}",
- Bypass = string.Join(";", ProxyService.LanIp)
- };
- service.Global();
- }
+ Server = $"127.0.0.1:{Global.Settings.HTTPLocalPort}",
+ Bypass = string.Join(";", ProxyService.LanIp)
+ };
+ service.Global();
}
}
- catch (Exception e)
- {
- if (MessageBoxX.Show(i18N.Translate("Failed to set the system proxy, it may be caused by the lack of dependent programs. Do you want to jump to Netch's official website to download dependent programs?"), confirm: true) == DialogResult.OK) Process.Start("https://netch.org/#/?id=%e4%be%9d%e8%b5%96");
-
- Logging.Error("设置系统代理失败" + e);
- return false;
- }
-
- return true;
}
///
diff --git a/Netch/Controllers/IModeController.cs b/Netch/Controllers/IModeController.cs
index 5fc5e2e0..3760597b 100644
--- a/Netch/Controllers/IModeController.cs
+++ b/Netch/Controllers/IModeController.cs
@@ -9,6 +9,6 @@ namespace Netch.Controllers
///
/// 模式
/// 是否成功
- public abstract bool Start(in Mode mode);
+ public abstract void Start(in Mode mode);
}
}
\ No newline at end of file
diff --git a/Netch/Controllers/IServerController.cs b/Netch/Controllers/IServerController.cs
index 62dceee2..8b135026 100644
--- a/Netch/Controllers/IServerController.cs
+++ b/Netch/Controllers/IServerController.cs
@@ -14,7 +14,7 @@ namespace Netch.Controllers
/// 服务器
/// 模式
/// 是否启动成功
- public abstract bool Start(in Server s, in Mode mode);
+ public abstract void Start(in Server s, in Mode mode);
}
public static class ServerControllerExtension
diff --git a/Netch/Controllers/MainController.cs b/Netch/Controllers/MainController.cs
index 930086b8..0b1c1458 100644
--- a/Netch/Controllers/MainController.cs
+++ b/Netch/Controllers/MainController.cs
@@ -3,11 +3,9 @@ using System.IO;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
-using Netch.Forms;
using Netch.Models;
using Netch.Servers.Socks5;
using Netch.Utils;
-using static Netch.Forms.MainForm;
using static Netch.Utils.PortHelper;
namespace Netch.Controllers
@@ -51,14 +49,15 @@ namespace Netch.Controllers
/// 服务器
/// 模式
/// 是否启动成功
- public static async Task Start(Server server, Mode mode)
+ ///
+ public static async Task Start(Server server, Mode mode)
{
Logging.Info($"启动主控制器: {server.Type} [{mode.Type}]{mode.Remark}");
Server = server;
Mode = mode;
if (server is Socks5 && mode.Type == 4)
- return false;
+ throw new MessageException("Already Socks5 Server");
// 刷新DNS缓存
NativeMethods.FlushDNSResolverCache();
@@ -69,15 +68,11 @@ namespace Netch.Controllers
}
catch (Exception)
{
- MessageBoxX.Show("No internet connection");
- return false;
+ throw new MessageException(i18N.Translate("No internet connection"));
}
if (Global.Settings.ResolveServerHostname && DNS.Lookup(server.Hostname) == null)
- {
- MessageBoxX.Show("Lookup Server hostname failed");
- return false;
- }
+ throw new MessageException(i18N.Translate("Lookup Server hostname failed"));
// 添加Netch到防火墙
_ = Task.Run(Firewall.AddNetchFwRules);
@@ -86,32 +81,15 @@ namespace Netch.Controllers
{
if (!ModeHelper.SkipServerController(server, mode))
{
- if (!await Task.Run(() => StartServer(server, mode, ref _serverController)))
- throw new StartFailedException();
+ await Task.Run(() => StartServer(server, mode, out _serverController));
StatusPortInfoText.UpdateShareLan();
}
- if (!await StartMode(mode))
- throw new StartFailedException();
-
- return true;
+ await Task.Run(() => StartMode(mode));
}
catch (Exception e)
{
- switch (e)
- {
- case DllNotFoundException _:
- case FileNotFoundException _:
- MessageBoxX.Show(e.Message + "\n\n" + i18N.Translate("Missing File or runtime components"), owner: Global.MainForm);
- break;
- case StartFailedException _:
- break;
- default:
- Logging.Error($"主控制器未处理异常: {e}");
- break;
- }
-
try
{
await Stop();
@@ -121,69 +99,66 @@ namespace Netch.Controllers
// ignored
}
- return false;
+ switch (e)
+ {
+ case DllNotFoundException:
+ case FileNotFoundException:
+ throw new Exception(e.Message + "\n\n" + i18N.Translate("Missing File or runtime components"));
+ case MessageException:
+ throw;
+ default:
+ Logging.Error(e.ToString());
+ Utils.Utils.Open(Logging.LogFile);
+ throw new MessageException($"未处理异常\n{e.Message}");
+ }
}
}
- private static bool StartServer(Server server, Mode mode, ref IServerController controller)
+ private static void StartServer(Server server, Mode mode, out IServerController controller)
{
controller = ServerHelper.GetUtilByTypeName(server.Type).GetController();
if (controller is Guard instanceController)
Utils.Utils.KillProcessByName(instanceController.MainFile);
- if (!PortCheckAndShowMessageBox(controller.Socks5LocalPort(), "Socks5"))
- return false;
+ PortCheck(controller.Socks5LocalPort(), "Socks5");
Global.MainForm.StatusText(i18N.TranslateFormat("Starting {0}", controller.Name));
- if (controller.Start(in server, mode))
+
+ controller.Start(in server, mode);
+ if (controller is Guard {Instance: { }} guard)
+ Task.Run(() =>
+ {
+ Thread.Sleep(1000);
+ Global.Job.AddProcess(guard.Instance);
+ });
+
+ if (server is Socks5 socks5)
{
- if (controller is Guard guard)
- if (guard.Instance != null)
- Task.Run(() =>
- {
- Thread.Sleep(1000);
- Global.Job.AddProcess(guard.Instance);
- });
-
- if (server is Socks5 socks5)
- {
- if (socks5.Auth())
- StatusPortInfoText.Socks5Port = controller.Socks5LocalPort();
- }
- else
- {
+ if (socks5.Auth())
StatusPortInfoText.Socks5Port = controller.Socks5LocalPort();
- }
-
- return true;
}
-
- return false;
+ else
+ {
+ StatusPortInfoText.Socks5Port = controller.Socks5LocalPort();
+ }
}
- private static async Task StartMode(Mode mode)
+ private static void StartMode(Mode mode)
{
ModeController = ModeHelper.GetModeControllerByType(mode.Type, out var port, out var portName, out var portType);
if (ModeController == null)
- return true;
+ throw new MessageException("未知模式类型");
if (port != null)
- if (!PortCheckAndShowMessageBox((ushort) port, portName, portType))
- return false;
+ PortCheck((ushort) port, portName, portType);
Global.MainForm.StatusText(i18N.TranslateFormat("Starting {0}", ModeController.Name));
- if (await Task.Run(() => ModeController.Start(mode)))
- {
- if (ModeController is Guard guard)
- if (guard.Instance != null)
- Global.Job.AddProcess(guard.Instance);
- return true;
- }
-
- return false;
+ ModeController.Start(mode);
+ if (ModeController is Guard {Instance: { }} guard)
+ Global.Job.AddProcess(guard.Instance);
}
///
@@ -205,31 +180,31 @@ namespace Netch.Controllers
ServerController = null;
}
- ///
- /// 检查端口是否被占用,
- /// 被占用则弹窗提示, 确认后抛出异常
- ///
- public static bool PortCheckAndShowMessageBox(ushort port, string portName, PortType portType = PortType.Both)
+ public static void PortCheck(ushort port, string portName, PortType portType = PortType.Both)
{
try
{
CheckPort(port, portType);
- return true;
}
catch (PortInUseException)
{
- MessageBoxX.Show(i18N.TranslateFormat("The {0} port is in use.", $"{portName} ({port})"));
- return false;
+ throw new MessageException(i18N.TranslateFormat("The {0} port is in use.", $"{portName} ({port})"));
}
catch (PortReservedException)
{
- MessageBoxX.Show(i18N.TranslateFormat("The {0} port is reserved by system.", $"{portName} ({port})"));
- return false;
+ throw new MessageException(i18N.TranslateFormat("The {0} port is reserved by system.", $"{portName} ({port})"));
}
}
}
- public class StartFailedException : Exception
+ public class MessageException : Exception
{
+ public MessageException()
+ {
+ }
+
+ public MessageException(string message) : base(message)
+ {
+ }
}
}
\ No newline at end of file
diff --git a/Netch/Controllers/NFController.cs b/Netch/Controllers/NFController.cs
index 0439b8f3..0ea38af8 100644
--- a/Netch/Controllers/NFController.cs
+++ b/Netch/Controllers/NFController.cs
@@ -48,10 +48,9 @@ namespace Netch.Controllers
public string Name { get; } = "Redirector";
- public bool Start(in Mode mode)
+ public void Start(in Mode mode)
{
- if (!CheckDriver())
- return false;
+ CheckDriver();
#region aio_dial
@@ -85,10 +84,7 @@ namespace Netch.Controllers
}
if (!CheckRule(mode.FullRule, out var list))
- {
- MessageBoxX.Show($"\"{string.Join("", list.Select(s => s + "\n"))}\" does not conform to C++ regular expression syntax");
- return false;
- }
+ throw new MessageException($"\"{string.Join("", list.Select(s => s + "\n"))}\" does not conform to C++ regular expression syntax");
SetName(mode);
@@ -103,7 +99,8 @@ namespace Netch.Controllers
DNS.OutboundDNS = Global.Settings.ModifiedDNS;
}
- return aio_init();
+ if (!aio_init())
+ throw new MessageException("Redirector Start failed, run Netch with \"-console\" argument");
}
public void Stop()
@@ -150,7 +147,7 @@ namespace Netch.Controllers
}
}
- private static bool CheckDriver()
+ private static void CheckDriver()
{
var binFileVersion = Utils.Utils.GetFileVersion(BinDriver);
var systemFileVersion = Utils.Utils.GetFileVersion(SystemDriver);
@@ -158,50 +155,33 @@ namespace Netch.Controllers
Logging.Info("内置驱动版本: " + binFileVersion);
Logging.Info("系统驱动版本: " + systemFileVersion);
- if (!File.Exists(BinDriver))
+ if (!File.Exists(SystemDriver))
{
- Logging.Warning("内置驱动不存在");
- if (File.Exists(SystemDriver))
- {
- Logging.Warning("使用系统驱动");
- return true;
- }
-
- Logging.Error("未安装驱动");
- return false;
+ InstallDriver();
+ return;
}
- if (!File.Exists(SystemDriver))
- return InstallDriver();
-
- var updateFlag = false;
-
+ var reinstallFlag = false;
if (Version.TryParse(binFileVersion, out var binResult) && Version.TryParse(systemFileVersion, out var systemResult))
{
if (binResult.CompareTo(systemResult) > 0)
- {
// Bin greater than Installed
- updateFlag = true;
- }
- else
- {
- // Installed greater than Bin
- if (systemResult.Major != binResult.Major)
- // API breaking changes
- updateFlag = true;
- }
+ reinstallFlag = true;
+ else if (systemResult.Major != binResult.Major)
+ // Installed greater than Bin but Major Version Difference (has breaking changes), do downgrade
+ reinstallFlag = true;
}
else
{
if (!systemFileVersion.Equals(binFileVersion))
- updateFlag = true;
+ reinstallFlag = true;
}
- if (!updateFlag) return true;
+ if (!reinstallFlag) return;
Logging.Info("更新驱动");
UninstallDriver();
- return InstallDriver();
+ InstallDriver();
}
private void SetServer(in PortType portType)
@@ -321,9 +301,13 @@ namespace Netch.Controllers
/// 安装 NF 驱动
///
/// 驱动是否安装成功
- public static bool InstallDriver()
+ public static void InstallDriver()
{
Logging.Info("安装 NF 驱动");
+
+ if (!File.Exists(BinDriver))
+ throw new MessageException(i18N.Translate("builtin driver files missing, can't install NF driver"));
+
try
{
File.Copy(BinDriver, SystemDriver);
@@ -331,7 +315,7 @@ namespace Netch.Controllers
catch (Exception e)
{
Logging.Error("驱动复制失败\n" + e);
- return false;
+ throw new MessageException($"Copy NF driver file failed\n{e.Message}");
}
Global.MainForm.StatusText(i18N.Translate("Register driver"));
@@ -344,10 +328,8 @@ namespace Netch.Controllers
else
{
Logging.Error($"注册驱动失败,返回值:{result}");
- return false;
+ throw new MessageException($"Register NF driver failed\n{result}");
}
-
- return true;
}
///
diff --git a/Netch/Controllers/PrivoxyController.cs b/Netch/Controllers/PrivoxyController.cs
index a9634c77..296eaac3 100644
--- a/Netch/Controllers/PrivoxyController.cs
+++ b/Netch/Controllers/PrivoxyController.cs
@@ -12,11 +12,16 @@ namespace Netch.Controllers
RedirectStd = false;
}
- public override string Name { get; } = "Privoxy";
-
public override string MainFile { get; protected set; } = "Privoxy.exe";
- public bool Start(Server server, Mode mode)
+ public override string Name { get; } = "Privoxy";
+
+ public override void Stop()
+ {
+ StopInstance();
+ }
+
+ public void Start(Server server)
{
var text = new StringBuilder(File.ReadAllText("bin\\default.conf"));
@@ -34,12 +39,7 @@ namespace Netch.Controllers
File.WriteAllText("data\\privoxy.conf", text.ToString());
- return StartInstanceAuto("..\\data\\privoxy.conf");
- }
-
- public override void Stop()
- {
- StopInstance();
+ StartInstanceAuto("..\\data\\privoxy.conf");
}
}
}
\ No newline at end of file
diff --git a/Netch/Controllers/TUNTAPController.cs b/Netch/Controllers/TUNTAPController.cs
index 0994e95a..5bb5f9f1 100644
--- a/Netch/Controllers/TUNTAPController.cs
+++ b/Netch/Controllers/TUNTAPController.cs
@@ -37,28 +37,19 @@ namespace Netch.Controllers
public override string Name { get; } = "tun2socks";
- public bool Start(in Mode mode)
+ public void Start(in Mode mode)
{
var server = MainController.Server;
// 查询服务器 IP 地址
_serverAddresses = DNS.Lookup(server.Hostname);
// 查找出口适配器
- if (!Utils.Utils.SearchOutboundAdapter())
- return false;
+ Utils.Utils.SearchOutboundAdapter();
// 查找并安装 TAP 适配器
- if (!SearchTapAdapter())
- {
- if (!AddTap())
- {
- Logging.Error("Tap 适配器安装失败");
- return false;
- }
-
- SearchTapAdapter();
- }
-
+ if (string.IsNullOrEmpty(TUNTAP.GetComponentID()))
+ AddTap();
+ SearchTapAdapter();
SetupRouteTable(mode);
@@ -79,14 +70,9 @@ namespace Netch.Controllers
}
else
{
- if (!MainController.PortCheckAndShowMessageBox(53, "DNS"))
- return false;
+ MainController.PortCheck(53, "DNS");
- if (!DNSController.Start())
- {
- Logging.Error("AioDNS 启动失败");
- return false;
- }
+ DNSController.Start();
dns = "127.0.0.1";
}
@@ -103,7 +89,7 @@ namespace Netch.Controllers
if (Global.Settings.TUNTAP.UseFakeDNS && Global.Flags.SupportFakeDns)
argument.Append("-fakeDns ");
- return StartInstanceAuto(argument.ToString(), ProcessPriorityClass.RealTime);
+ StartInstanceAuto(argument.ToString(), ProcessPriorityClass.RealTime);
}
///
@@ -235,7 +221,7 @@ namespace Netch.Controllers
///
/// 搜索出口和TUNTAP适配器
///
- public static bool SearchTapAdapter()
+ public static void SearchTapAdapter()
{
Global.TUNTAP.Adapter = null;
Global.TUNTAP.Index = -1;
@@ -244,31 +230,16 @@ namespace Netch.Controllers
// 搜索 TUN/TAP 适配器的索引
if (string.IsNullOrEmpty(Global.TUNTAP.ComponentID))
{
- Logging.Info("TAP 适配器未安装");
- return false;
+ const string s = "TAP 适配器未安装";
+ Logging.Info(s);
+ throw new Exception(s);
}
// 根据 ComponentID 寻找 Tap适配器
- 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}");
- return true;
- }
- catch (Exception e)
- {
- var msg = e switch
- {
- InvalidOperationException _ => $"找不到标识符为 {Global.TUNTAP.ComponentID} 的 TAP 适配器: {e.Message}",
- NetworkInformationException _ => $"获取 Tap 适配器信息错误: {e.Message}",
- _ => $"Tap 适配器其他异常: {e}"
- };
- Logging.Error(msg);
- return false;
- }
+ 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}");
}
private static bool AddTap()
@@ -278,8 +249,9 @@ namespace Netch.Controllers
Thread.Sleep(1000);
if (string.IsNullOrEmpty(Global.TUNTAP.ComponentID = TUNTAP.GetComponentID()))
{
- Logging.Error("找不到 TAP 适配器,驱动可能安装失败");
- return false;
+ const string s = "TAP 驱动安装失败,找不到 ComponentID 注册表项";
+ Logging.Error(s);
+ throw new Exception(s);
}
return true;
diff --git a/Netch/Forms/MainForm.cs b/Netch/Forms/MainForm.cs
index 908f85ad..aee9f13d 100644
--- a/Netch/Forms/MainForm.cs
+++ b/Netch/Forms/MainForm.cs
@@ -333,9 +333,10 @@ namespace Netch.Forms
Configuration.Save();
StatusText(i18N.Translate("Subscription updated"));
}
- catch (Exception)
+ catch (Exception e)
{
- // ignored
+ NotifyTip(i18N.Translate("update servers failed") + "\n" + e.Message, info: false);
+ Logging.Error("更新服务器 失败!" + e);
}
finally
{
@@ -453,9 +454,7 @@ namespace Netch.Forms
finally
{
if (useProxy)
- {
await MainController.Stop();
- }
StatusText();
Enabled = true;
@@ -595,10 +594,15 @@ namespace Netch.Forms
State = State.Starting;
- if (!await MainController.Start(server, mode))
+ try
+ {
+ await MainController.Start(server, mode);
+ }
+ catch (Exception exception)
{
State = State.Stopped;
StatusText(i18N.Translate("Start failed"));
+ MessageBoxX.Show(exception.Message);
return;
}
@@ -1117,52 +1121,6 @@ namespace Netch.Forms
return state == State.Waiting || state == State.Stopped;
}
- public static class StatusPortInfoText
- {
- private static ushort? _socks5Port;
- private static ushort? _httpPort;
- private static bool _shareLan;
-
- public static ushort HttpPort
- {
- set => _httpPort = value;
- }
-
- public static ushort Socks5Port
- {
- set => _socks5Port = value;
- }
-
- public static string Value
- {
- get
- {
- var strings = new List();
-
- if (_socks5Port != null)
- strings.Add($"Socks5 {i18N.Translate("Local Port", ": ")}{_socks5Port}");
-
- if (_httpPort != null)
- strings.Add($"HTTP {i18N.Translate("Local Port", ": ")}{_httpPort}");
-
- if (!strings.Any())
- return string.Empty;
-
- return $" ({(_shareLan ? i18N.Translate("Allow other Devices to connect") + " " : "")}{string.Join(" | ", strings)})";
- }
- }
-
- public static void UpdateShareLan()
- {
- _shareLan = Global.Settings.LocalAddress != "127.0.0.1";
- }
-
- public static void Reset()
- {
- _httpPort = _socks5Port = null;
- }
- }
-
///
/// 更新状态栏文本
///
diff --git a/Netch/Models/StatusText.cs b/Netch/Models/StatusText.cs
new file mode 100644
index 00000000..3a80f417
--- /dev/null
+++ b/Netch/Models/StatusText.cs
@@ -0,0 +1,52 @@
+using System.Collections.Generic;
+using System.Linq;
+using Netch.Utils;
+
+namespace Netch.Models
+{
+ public static class StatusPortInfoText
+ {
+ private static ushort? _socks5Port;
+ private static ushort? _httpPort;
+ private static bool _shareLan;
+
+ public static ushort HttpPort
+ {
+ set => _httpPort = value;
+ }
+
+ public static ushort Socks5Port
+ {
+ set => _socks5Port = value;
+ }
+
+ public static string Value
+ {
+ get
+ {
+ var strings = new List();
+
+ if (_socks5Port != null)
+ strings.Add($"Socks5 {i18N.Translate("Local Port", ": ")}{_socks5Port}");
+
+ if (_httpPort != null)
+ strings.Add($"HTTP {i18N.Translate("Local Port", ": ")}{_httpPort}");
+
+ if (!strings.Any())
+ return string.Empty;
+
+ return $" ({(_shareLan ? i18N.Translate("Allow other Devices to connect") + " " : "")}{string.Join(" | ", strings)})";
+ }
+ }
+
+ public static void UpdateShareLan()
+ {
+ _shareLan = Global.Settings.LocalAddress != "127.0.0.1";
+ }
+
+ public static void Reset()
+ {
+ _httpPort = _socks5Port = null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Netch/Servers/Shadowsocks/SSController.cs b/Netch/Servers/Shadowsocks/SSController.cs
index 550eb85f..87a659b6 100644
--- a/Netch/Servers/Shadowsocks/SSController.cs
+++ b/Netch/Servers/Shadowsocks/SSController.cs
@@ -8,15 +8,14 @@ namespace Netch.Servers.Shadowsocks
{
public class SSController : Guard, IServerController
{
- public override string Name { get; } = "Shadowsocks";
+ public bool DllFlag;
public override string MainFile { get; protected set; } = "Shadowsocks.exe";
+ public override string Name { get; } = "Shadowsocks";
public ushort? Socks5LocalPort { get; set; }
public string LocalAddress { get; set; }
- public bool DllFlag;
-
- public bool Start(in Server s, in Mode mode)
+ public void Start(in Server s, in Mode mode)
{
var server = (Shadowsocks) s;
@@ -33,8 +32,7 @@ namespace Netch.Servers.Shadowsocks
if (!ShadowsocksDLL.Info(client, remote, passwd, method))
{
State = State.Stopped;
- Logging.Error("DLL SS INFO 设置失败!");
- return false;
+ throw new MessageException("DLL SS INFO 设置失败!");
}
Logging.Info("DLL SS INFO 设置成功!");
@@ -42,13 +40,12 @@ namespace Netch.Servers.Shadowsocks
if (!ShadowsocksDLL.Start())
{
State = State.Stopped;
- Logging.Error("DLL SS 启动失败!");
- return false;
+ throw new MessageException("DLL SS 启动失败!");
}
Logging.Info("DLL SS 启动成功!");
State = State.Started;
- return true;
+ return;
}
#region Argument
@@ -70,7 +67,7 @@ namespace Netch.Servers.Shadowsocks
#endregion
- return StartInstanceAuto(argument.ToString());
+ StartInstanceAuto(argument.ToString());
}
public override void Stop()
diff --git a/Netch/Servers/ShadowsocksR/SSRController.cs b/Netch/Servers/ShadowsocksR/SSRController.cs
index ab2c91f0..73138748 100644
--- a/Netch/Servers/ShadowsocksR/SSRController.cs
+++ b/Netch/Servers/ShadowsocksR/SSRController.cs
@@ -13,7 +13,7 @@ namespace Netch.Servers.ShadowsocksR
public ushort? Socks5LocalPort { get; set; }
public string LocalAddress { get; set; }
- public bool Start(in Server s, in Mode mode)
+ public void Start(in Server s, in Mode mode)
{
var server = (ShadowsocksR) s;
@@ -38,7 +38,7 @@ namespace Netch.Servers.ShadowsocksR
#endregion
- return StartInstanceAuto(argument.ToString());
+ StartInstanceAuto(argument.ToString());
}
public override void Stop()
diff --git a/Netch/Servers/Socks5/S5Controller.cs b/Netch/Servers/Socks5/S5Controller.cs
index c3e31819..e2d04916 100644
--- a/Netch/Servers/Socks5/S5Controller.cs
+++ b/Netch/Servers/Socks5/S5Controller.cs
@@ -7,13 +7,11 @@ namespace Netch.Servers.Socks5
{
public override string Name { get; } = "Socks5";
- public override bool Start(in Server s, in Mode mode)
+ public override void Start(in Server s, in Mode mode)
{
var server = (Socks5) s;
if (server.Auth())
- return base.Start(s, mode);
-
- return true;
+ base.Start(s, mode);
}
}
}
\ No newline at end of file
diff --git a/Netch/Servers/Trojan/TrojanController.cs b/Netch/Servers/Trojan/TrojanController.cs
index a4d00e70..5a7b9564 100644
--- a/Netch/Servers/Trojan/TrojanController.cs
+++ b/Netch/Servers/Trojan/TrojanController.cs
@@ -20,7 +20,7 @@ namespace Netch.Servers.Trojan
public ushort? Socks5LocalPort { get; set; }
public string LocalAddress { get; set; }
- public bool Start(in Server s, in Mode mode)
+ public void Start(in Server s, in Mode mode)
{
var server = (Trojan) s;
var trojanConfig = new TrojanConfig
@@ -42,7 +42,7 @@ namespace Netch.Servers.Trojan
{
NullValueHandling = NullValueHandling.Ignore
}));
- return StartInstanceAuto("-c ..\\data\\last.json");
+ StartInstanceAuto("-c ..\\data\\last.json");
}
public override void Stop()
diff --git a/Netch/Servers/V2ray/V2rayController.cs b/Netch/Servers/V2ray/V2rayController.cs
index 9bccf93e..0725425d 100644
--- a/Netch/Servers/V2ray/V2rayController.cs
+++ b/Netch/Servers/V2ray/V2rayController.cs
@@ -17,10 +17,10 @@ namespace Netch.Servers.V2ray
public override string Name { get; } = "Xray";
public ushort? Socks5LocalPort { get; set; }
public string LocalAddress { get; set; }
- public virtual bool Start(in Server s, in Mode mode)
+ public virtual void Start(in Server s, in Mode mode)
{
File.WriteAllText("data\\last.json", V2rayConfigUtils.GenerateClientConfig(s, mode));
- return StartInstanceAuto("-config ..\\data\\last.json");
+ StartInstanceAuto("-config ..\\data\\last.json");
}
public override void Stop()
diff --git a/Netch/Updater/Updater.cs b/Netch/Updater/Updater.cs
index 4ee34456..b358655a 100644
--- a/Netch/Updater/Updater.cs
+++ b/Netch/Updater/Updater.cs
@@ -4,7 +4,6 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
-using System.Windows.Forms;
using Netch.Forms;
using Netch.Properties;
diff --git a/Netch/Utils/ModeHelper.cs b/Netch/Utils/ModeHelper.cs
index a751e077..6950ce83 100644
--- a/Netch/Utils/ModeHelper.cs
+++ b/Netch/Utils/ModeHelper.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using Netch.Controllers;
-using Netch.Forms;
using Netch.Models;
using Netch.Servers.Shadowsocks;
using Netch.Servers.Socks5;
@@ -161,14 +160,14 @@ namespace Netch.Utils
port = Global.Settings.HTTPLocalPort;
portName = "HTTP";
portType = PortType.TCP;
- MainForm.StatusPortInfoText.HttpPort = (ushort) port;
+ StatusPortInfoText.HttpPort = (ushort) port;
break;
case 4:
modeController = null;
break;
default:
Logging.Error("未知模式类型");
- throw new StartFailedException();
+ throw new MessageException();
}
return modeController;
diff --git a/Netch/Utils/PortHelper.cs b/Netch/Utils/PortHelper.cs
index 442657c1..75937c84 100644
--- a/Netch/Utils/PortHelper.cs
+++ b/Netch/Utils/PortHelper.cs
@@ -163,8 +163,20 @@ namespace Netch.Utils
public class PortInUseException : Exception
{
+ public PortInUseException(string message) : base(message)
+ {
+ }
+ public PortInUseException()
+ {
+ }
}
public class PortReservedException : Exception
{
+ public PortReservedException(string message) : base(message)
+ {
+ }
+ public PortReservedException()
+ {
+ }
}
}
\ No newline at end of file
diff --git a/Netch/Utils/Utils.cs b/Netch/Utils/Utils.cs
index 048a88ef..b267348b 100644
--- a/Netch/Utils/Utils.cs
+++ b/Netch/Utils/Utils.cs
@@ -13,6 +13,7 @@ using System.Threading.Tasks;
using System.Windows.Forms;
using MaxMind.GeoIP2;
using Microsoft.Win32.TaskScheduler;
+using Vanara.PInvoke;
using Task = System.Threading.Tasks.Task;
namespace Netch.Utils
@@ -136,46 +137,37 @@ namespace Netch.Utils
return File.Exists(file) ? FileVersionInfo.GetVersionInfo(file).FileVersion : string.Empty;
}
- public static bool SearchOutboundAdapter(bool logging = true)
+ public static void SearchOutboundAdapter(bool logging = true)
{
// 寻找出口适配器
- if (Vanara.PInvoke.IpHlpApi.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse("114.114.114.114").GetAddressBytes(), 0),
+ if (IpHlpApi.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse("114.114.114.114").GetAddressBytes(), 0),
0, out var pRoute) != 0)
{
Logging.Error("GetBestRoute 搜索失败");
- return false;
+ throw new Exception("GetBestRoute 搜索失败");
}
Global.Outbound.Index = (int) pRoute.dwForwardIfIndex;
// 根据 IP Index 寻找 出口适配器
- try
+ var adapter = NetworkInterface.GetAllNetworkInterfaces().First(_ =>
{
- var adapter = NetworkInterface.GetAllNetworkInterfaces().First(_ =>
+ try
{
- try
- {
- return _.GetIPProperties().GetIPv4Properties().Index == Global.Outbound.Index;
- }
- catch
- {
- return false;
- }
- });
- Global.Outbound.Adapter = adapter;
- Global.Outbound.Gateway = new IPAddress(pRoute.dwForwardNextHop.S_un_b);
- if (logging)
- {
- Logging.Info($"出口 IPv4 地址:{Global.Outbound.Address}");
- Logging.Info($"出口 网关 地址:{Global.Outbound.Gateway}");
- Logging.Info($"出口适配器:{adapter.Name} {adapter.Id} {adapter.Description}, index: {Global.Outbound.Index}");
+ return _.GetIPProperties().GetIPv4Properties().Index == Global.Outbound.Index;
}
+ catch
+ {
+ return false;
+ }
+ });
+ Global.Outbound.Adapter = adapter;
+ Global.Outbound.Gateway = new IPAddress(pRoute.dwForwardNextHop.S_un_b);
- return true;
- }
- catch (Exception e)
+ if (logging)
{
- Logging.Error($"找不到出口IP所在网卡: {e}");
- return false;
+ Logging.Info($"出口 IPv4 地址:{Global.Outbound.Address}");
+ Logging.Info($"出口 网关 地址:{Global.Outbound.Gateway}");
+ Logging.Info($"出口适配器:{adapter.Name} {adapter.Id} {adapter.Description}, index: {Global.Outbound.Index}");
}
}