mirror of
https://github.com/netchx/netch.git
synced 2026-05-11 23:45:06 +08:00
初步重构 Contollers
This commit is contained in:
@@ -1,20 +1,21 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using Netch.Forms;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class DNSController
|
||||
public class DNSController : Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// 进程实例
|
||||
/// </summary>
|
||||
public Process Instance;
|
||||
public DNSController()
|
||||
{
|
||||
MainName = "unbound";
|
||||
ExtFiles = new[] {"unbound-service.conf", "forward-zone.conf"};
|
||||
ready = BeforeStartProgress();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启动DNS服务
|
||||
/// 启动DNS服务
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool Start()
|
||||
@@ -22,13 +23,7 @@ namespace Netch.Controllers
|
||||
MainForm.Instance.StatusText(i18N.Translate("Starting dns Service"));
|
||||
try
|
||||
{
|
||||
if (!File.Exists("bin\\unbound.exe") && !File.Exists("bin\\unbound-service.conf") && !File.Exists("bin\\forward-zone.conf"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Instance = MainController.GetProcess();
|
||||
Instance.StartInfo.FileName = "bin\\unbound.exe";
|
||||
Instance = MainController.GetProcess("bin\\unbound.exe");
|
||||
|
||||
Instance.StartInfo.Arguments = "-c unbound-service.conf -v";
|
||||
|
||||
@@ -49,35 +44,9 @@ namespace Netch.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Instance != null && !Instance.HasExited)
|
||||
{
|
||||
Instance.Kill();
|
||||
Instance.WaitForExit();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Info(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(e.Data))
|
||||
{
|
||||
if (File.Exists("logging\\dns-unbound.log"))
|
||||
{
|
||||
File.Delete("logging\\dns-unbound.log");
|
||||
}
|
||||
File.AppendAllText("logging\\dns-unbound.log", $"{e.Data}\r\n");
|
||||
}
|
||||
WriteLog(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,16 +9,16 @@ namespace Netch.Controllers
|
||||
{
|
||||
public class HTTPController
|
||||
{
|
||||
private bool prevEnabled;
|
||||
private string prevBypass, prevHTTP, prevPAC;
|
||||
|
||||
/// <summary>
|
||||
/// 实例
|
||||
/// </summary>
|
||||
public PrivoxyController pPrivoxyController = new PrivoxyController();
|
||||
|
||||
private string prevBypass, prevHTTP, prevPAC;
|
||||
private bool prevEnabled;
|
||||
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">服务器</param>
|
||||
/// <param name="mode">模式</param>
|
||||
@@ -30,10 +30,7 @@ namespace Netch.Controllers
|
||||
{
|
||||
if (server.Type == "Socks5")
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(server.Username) && !string.IsNullOrWhiteSpace(server.Password))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(server.Username) && !string.IsNullOrWhiteSpace(server.Password)) return false;
|
||||
|
||||
pPrivoxyController.Start(server, mode);
|
||||
}
|
||||
@@ -42,17 +39,12 @@ namespace Netch.Controllers
|
||||
pPrivoxyController.Start(server, mode);
|
||||
}
|
||||
|
||||
if (mode.Type != 5)
|
||||
{
|
||||
NativeMethods.SetGlobal($"127.0.0.1:{Global.Settings.HTTPLocalPort}", "<local>");
|
||||
}
|
||||
if (mode.Type != 5) NativeMethods.SetGlobal($"127.0.0.1:{Global.Settings.HTTPLocalPort}", "<local>");
|
||||
}
|
||||
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");
|
||||
}
|
||||
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.Info("设置系统代理失败" + e);
|
||||
return false;
|
||||
}
|
||||
@@ -69,18 +61,16 @@ namespace Netch.Controllers
|
||||
prevPAC = prevHTTP = prevBypass = "";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
prevPAC = registry.GetValue("AutoConfigURL")?.ToString() ?? "";
|
||||
if ((registry.GetValue("ProxyEnable")?.Equals(1) ?? false) || prevPAC != "")
|
||||
{
|
||||
prevEnabled = true;
|
||||
}
|
||||
if ((registry.GetValue("ProxyEnable")?.Equals(1) ?? false) || prevPAC != "") prevEnabled = true;
|
||||
|
||||
prevHTTP = registry.GetValue("ProxyServer")?.ToString() ?? "";
|
||||
prevBypass = registry.GetValue("ProxyOverride")?.ToString() ?? "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// 停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
@@ -108,4 +98,4 @@ namespace Netch.Controllers
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
101
Netch/Controllers/Interface/Controller.cs
Normal file
101
Netch/Controllers/Interface/Controller.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class Controller
|
||||
{
|
||||
protected string[] ExtFiles;
|
||||
|
||||
/// <summary>
|
||||
/// 进程实例
|
||||
/// </summary>
|
||||
public Process Instance;
|
||||
|
||||
/// <summary>
|
||||
/// 程序名
|
||||
/// </summary>
|
||||
public string MainName;
|
||||
|
||||
public bool ready;
|
||||
|
||||
/// <summary>
|
||||
/// 当前状态
|
||||
/// </summary>
|
||||
protected State State = State.Waiting;
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Instance == null || Instance.HasExited) return;
|
||||
Instance.Kill();
|
||||
Instance.WaitForExit();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Info(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 杀残留进程,清除日志,检查文件
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected bool BeforeStartProgress()
|
||||
{
|
||||
var result = false;
|
||||
// 杀残留
|
||||
MainController.KillProcessByName(MainName);
|
||||
// 清日志
|
||||
try
|
||||
{
|
||||
if (File.Exists($"logging\\{MainName}.log")) File.Delete($"logging\\{MainName}.log");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
|
||||
// 检查文件
|
||||
if (!File.Exists($"bin\\{MainName}.exe")) Logging.Info($"bin\\{MainName}.exe 文件不存在");
|
||||
|
||||
if (ExtFiles == null)
|
||||
result = true;
|
||||
else
|
||||
foreach (var f in ExtFiles)
|
||||
if (!File.Exists($"bin\\{f}"))
|
||||
Logging.Info($"bin\\{f}.exe 文件不存在");
|
||||
|
||||
if (!ready) Logging.Info(MainName + "未能就绪");
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写日志
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
/// <returns>e是否为空</returns>
|
||||
public bool WriteLog(DataReceivedEventArgs e)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(e.Data)) return false;
|
||||
try
|
||||
{
|
||||
File.AppendAllText($"logging\\{MainName}.log", $@"{e.Data}{Global.EOF}");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Logging.Info($"写入{MainName}日志失败" + exception);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
32
Netch/Controllers/Interface/ServerClient.cs
Normal file
32
Netch/Controllers/Interface/ServerClient.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System.Diagnostics;
|
||||
using Netch.Models;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public abstract class ServerClient : Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">服务器</param>
|
||||
/// <param name="mode">模式</param>
|
||||
/// <returns>是否启动成功</returns>
|
||||
public abstract bool Start(Server server, Mode mode);
|
||||
|
||||
/// <summary>
|
||||
/// ServerClient 停止
|
||||
/// <param />
|
||||
/// 注意 对象类型 以调用子类 Stop() 方法
|
||||
/// </summary>
|
||||
public new void Stop()
|
||||
{
|
||||
base.Stop();
|
||||
|
||||
// SSController Stop()
|
||||
// 不能自动转换对象类型的兼容代码 :(
|
||||
if (Global.Settings.BootShadowsocksFromDLL) NativeMethods.Shadowsocks.Stop();
|
||||
}
|
||||
|
||||
public abstract void OnOutputDataReceived(object sender, DataReceivedEventArgs e);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
@@ -11,65 +12,34 @@ namespace Netch.Controllers
|
||||
{
|
||||
public class MainController
|
||||
{
|
||||
[DllImport("dnsapi", EntryPoint = "DnsFlushResolverCache")]
|
||||
public static extern uint FlushDNSResolverCache();
|
||||
public static Process GetProcess()
|
||||
{
|
||||
var process = new Process();
|
||||
process.StartInfo.WorkingDirectory = string.Format("{0}\\bin", Directory.GetCurrentDirectory());
|
||||
process.StartInfo.CreateNoWindow = true;
|
||||
process.StartInfo.RedirectStandardError = true;
|
||||
process.StartInfo.RedirectStandardInput = true;
|
||||
process.StartInfo.RedirectStandardOutput = true;
|
||||
process.StartInfo.UseShellExecute = false;
|
||||
process.EnableRaisingEvents = true;
|
||||
|
||||
return process;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SS 控制器
|
||||
/// </summary>
|
||||
public SSController pSSController;
|
||||
|
||||
/// <summary>
|
||||
/// SSR 控制器
|
||||
/// </summary>
|
||||
public SSRController pSSRController;
|
||||
|
||||
/// <summary>
|
||||
/// V2Ray 控制器
|
||||
/// </summary>
|
||||
public VMessController pVMessController;
|
||||
|
||||
/// <summary>
|
||||
/// Trojan 控制器
|
||||
/// </summary>
|
||||
public TrojanController pTrojanController;
|
||||
|
||||
/// <summary>
|
||||
/// NF 控制器
|
||||
/// </summary>
|
||||
public NFController pNFController;
|
||||
|
||||
/// <summary>
|
||||
/// HTTP 控制器
|
||||
/// </summary>
|
||||
public HTTPController pHTTPController;
|
||||
|
||||
/// <summary>
|
||||
/// NF 控制器
|
||||
/// </summary>
|
||||
public NFController pNFController;
|
||||
|
||||
/// <summary>
|
||||
/// NTT 控制器
|
||||
/// </summary>
|
||||
public NTTController pNTTController;
|
||||
|
||||
public ServerClient pServerClientController;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// TUN/TAP 控制器
|
||||
/// </summary>
|
||||
public TUNTAPController pTUNTAPController;
|
||||
|
||||
/// <summary>
|
||||
/// NTT 控制器
|
||||
/// </summary>
|
||||
public NTTController pNTTController;
|
||||
[DllImport("dnsapi", EntryPoint = "DnsFlushResolverCache")]
|
||||
public static extern uint FlushDNSResolverCache();
|
||||
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">服务器</param>
|
||||
/// <param name="mode">模式</param>
|
||||
@@ -79,207 +49,129 @@ namespace Netch.Controllers
|
||||
FlushDNSResolverCache();
|
||||
|
||||
var result = false;
|
||||
switch (server.Type)
|
||||
if (server.Type == "Socks5")
|
||||
{
|
||||
case "Socks5":
|
||||
if (mode.Type == 4)
|
||||
{
|
||||
result = mode.Type != 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (server.Type)
|
||||
{
|
||||
case "SS":
|
||||
pServerClientController = new SSController();
|
||||
break;
|
||||
case "SSR":
|
||||
pServerClientController = new SSRController();
|
||||
break;
|
||||
case "VMess":
|
||||
pServerClientController = new VMessController();
|
||||
break;
|
||||
case "Trojan":
|
||||
pServerClientController = new TrojanController();
|
||||
break;
|
||||
}
|
||||
|
||||
MainForm.Instance.StatusText(i18N.Translate("Starting ", pServerClientController.MainName));
|
||||
if (pServerClientController.ready) result = pServerClientController.Start(server, mode);
|
||||
}
|
||||
|
||||
if (result) // If server runs,then run mode
|
||||
switch (mode.Type)
|
||||
{
|
||||
case 0: // 进程代理模式
|
||||
pNFController ??= new NFController();
|
||||
pNTTController ??= new NTTController();
|
||||
if (pNFController.ready) result = pNFController.Start(server, mode, false);
|
||||
|
||||
if (!result && pNFController.ready)
|
||||
{
|
||||
MainForm.Instance.StatusText(i18N.Translate("Restarting Redirector"));
|
||||
Logging.Info("正常启动失败后尝试停止驱动服务再重新启动");
|
||||
//正常启动失败后尝试停止驱动服务再重新启动
|
||||
result = pNFController.Start(server, mode, true);
|
||||
}
|
||||
|
||||
if (result)
|
||||
Task.Run(() => pNTTController.Start());
|
||||
break;
|
||||
case 1: // TUN/TAP 黑名单代理模式
|
||||
case 2: // TUN/TAP 白名单代理模式
|
||||
pTUNTAPController ??= new TUNTAPController();
|
||||
pNTTController ??= new NTTController();
|
||||
result = pTUNTAPController.Start(server, mode);
|
||||
if (result)
|
||||
Task.Run(() => pNTTController.Start());
|
||||
break;
|
||||
case 3: // HTTP 系统代理和 Socks5 和 HTTP 代理模式
|
||||
case 5:
|
||||
pHTTPController ??= new HTTPController();
|
||||
result = pHTTPController.Start(server, mode);
|
||||
break;
|
||||
case 4: // Socks5 代理模式,不需要启动额外的Server
|
||||
break;
|
||||
default:
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
break;
|
||||
case "SS":
|
||||
KillProcess("Shadowsocks");
|
||||
if (pSSController == null)
|
||||
{
|
||||
pSSController = new SSController();
|
||||
}
|
||||
result = pSSController.Start(server, mode);
|
||||
break;
|
||||
case "SSR":
|
||||
KillProcess("ShadowsocksR");
|
||||
if (pSSRController == null)
|
||||
{
|
||||
pSSRController = new SSRController();
|
||||
}
|
||||
result = pSSRController.Start(server, mode);
|
||||
break;
|
||||
case "VMess":
|
||||
KillProcess("v2ray");
|
||||
if (pVMessController == null)
|
||||
{
|
||||
pVMessController = new VMessController();
|
||||
}
|
||||
result = pVMessController.Start(server, mode);
|
||||
break;
|
||||
case "Trojan":
|
||||
KillProcess("Trojan");
|
||||
if (pTrojanController == null)
|
||||
{
|
||||
pTrojanController = new TrojanController();
|
||||
}
|
||||
result = pTrojanController.Start(server, mode);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
if (mode.Type == 0)
|
||||
{
|
||||
if (pNFController == null)
|
||||
{
|
||||
pNFController = new NFController();
|
||||
}
|
||||
if (pNTTController == null)
|
||||
{
|
||||
pNTTController = new NTTController();
|
||||
}
|
||||
// 进程代理模式,启动 NF 控制器
|
||||
result = pNFController.Start(server, mode, false);
|
||||
if (!result)
|
||||
{
|
||||
MainForm.Instance.StatusText(i18N.Translate("Restarting Redirector"));
|
||||
Logging.Info("正常启动失败后尝试停止驱动服务再重新启动");
|
||||
//正常启动失败后尝试停止驱动服务再重新启动
|
||||
result = pNFController.Start(server, mode, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Task.Run(() => pNTTController.Start());
|
||||
}
|
||||
}
|
||||
else if (mode.Type == 1)
|
||||
{
|
||||
if (pTUNTAPController == null)
|
||||
{
|
||||
pTUNTAPController = new TUNTAPController();
|
||||
}
|
||||
if (pNTTController == null)
|
||||
{
|
||||
pNTTController = new NTTController();
|
||||
}
|
||||
// TUN/TAP 黑名单代理模式,启动 TUN/TAP 控制器
|
||||
result = pTUNTAPController.Start(server, mode);
|
||||
if (result)
|
||||
{
|
||||
Task.Run(() => pNTTController.Start());
|
||||
}
|
||||
}
|
||||
else if (mode.Type == 2)
|
||||
{
|
||||
if (pTUNTAPController == null)
|
||||
{
|
||||
pTUNTAPController = new TUNTAPController();
|
||||
}
|
||||
if (pNTTController == null)
|
||||
{
|
||||
pNTTController = new NTTController();
|
||||
}
|
||||
// TUN/TAP 白名单代理模式,启动 TUN/TAP 控制器
|
||||
result = pTUNTAPController.Start(server, mode);
|
||||
if (result)
|
||||
{
|
||||
Task.Run(() => pNTTController.Start());
|
||||
}
|
||||
}
|
||||
else if (mode.Type == 3 || mode.Type == 5)
|
||||
{
|
||||
if (pHTTPController == null)
|
||||
{
|
||||
pHTTPController = new HTTPController();
|
||||
}
|
||||
// HTTP 系统代理和 Socks5 和 HTTP 代理模式,启动 HTTP 控制器
|
||||
result = pHTTPController.Start(server, mode);
|
||||
}
|
||||
else if (mode.Type == 4)
|
||||
{
|
||||
// Socks5 代理模式,不需要启动额外的控制器
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
if (!result) Stop();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// 停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
if (pSSController != null)
|
||||
{
|
||||
pSSController.Stop();
|
||||
}
|
||||
else if (pSSRController != null)
|
||||
{
|
||||
pSSRController.Stop();
|
||||
}
|
||||
else if (pVMessController != null)
|
||||
{
|
||||
pVMessController.Stop();
|
||||
}
|
||||
else if (pTrojanController != null)
|
||||
{
|
||||
pTrojanController.Stop();
|
||||
}
|
||||
pServerClientController?.Stop();
|
||||
|
||||
if (pNFController != null)
|
||||
{
|
||||
pNFController.Stop();
|
||||
}
|
||||
else if (pTUNTAPController != null)
|
||||
{
|
||||
pTUNTAPController.Stop();
|
||||
}
|
||||
else if (pHTTPController != null)
|
||||
{
|
||||
pHTTPController.Stop();
|
||||
}
|
||||
else
|
||||
pHTTPController?.Stop();
|
||||
|
||||
if (pNTTController != null)
|
||||
{
|
||||
pNTTController.Stop();
|
||||
}
|
||||
pNTTController?.Stop();
|
||||
}
|
||||
|
||||
public void KillProcess(string name)
|
||||
public static Process GetProcess(string path = null)
|
||||
{
|
||||
var processes = Process.GetProcessesByName(name);
|
||||
foreach (var p in processes)
|
||||
var p = new Process
|
||||
{
|
||||
if (IsChildProcess(p, name))
|
||||
StartInfo =
|
||||
{
|
||||
p.Kill();
|
||||
}
|
||||
}
|
||||
Arguments = "",
|
||||
WorkingDirectory = $"{Global.NetchDir}\\bin",
|
||||
CreateNoWindow = true,
|
||||
RedirectStandardError = true,
|
||||
RedirectStandardInput = true,
|
||||
RedirectStandardOutput = true,
|
||||
UseShellExecute = false
|
||||
},
|
||||
EnableRaisingEvents = true
|
||||
};
|
||||
if (path != null) p.StartInfo.FileName = Path.GetFullPath(path);
|
||||
return p;
|
||||
}
|
||||
|
||||
private static bool IsChildProcess(Process process, string name)
|
||||
public static void KillProcessByName(string name)
|
||||
{
|
||||
bool result;
|
||||
try
|
||||
{
|
||||
var FileName = (Directory.GetCurrentDirectory() + "\\bin\\" + name + ".exe").ToLower();
|
||||
var procFileName = process.MainModule.FileName.ToLower();
|
||||
result = FileName.Equals(procFileName, StringComparison.Ordinal);
|
||||
foreach (var p in Process.GetProcessesByName(name))
|
||||
if (p.MainModule != null && p.MainModule.FileName.StartsWith(Global.NetchDir))
|
||||
p.Kill();
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (Win32Exception e)
|
||||
{
|
||||
Logging.Info(e.Message);
|
||||
result = false;
|
||||
Logging.Info($"结束进程 {name} 错误: " + e.Message);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,13 +11,8 @@ using nfapinet;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class NFController
|
||||
public class NFController : Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// 流量变动事件
|
||||
/// </summary>
|
||||
public event BandwidthUpdateHandler OnBandwidthUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// 流量变动处理器
|
||||
/// </summary>
|
||||
@@ -25,21 +20,22 @@ namespace Netch.Controllers
|
||||
/// <param name="download">下载</param>
|
||||
public delegate void BandwidthUpdateHandler(long upload, long download);
|
||||
|
||||
/// 驱动文件路径
|
||||
private readonly string _driverPath = $"{Environment.SystemDirectory}\\drivers\\netfilter2.sys";
|
||||
|
||||
public NFController()
|
||||
{
|
||||
MainName = "Redirector";
|
||||
ready = BeforeStartProgress();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 进程实例
|
||||
/// 流量变动事件
|
||||
/// </summary>
|
||||
public Process Instance;
|
||||
public event BandwidthUpdateHandler OnBandwidthUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// 当前状态
|
||||
/// </summary>
|
||||
public State State = State.Waiting;
|
||||
|
||||
// 生成驱动文件路径
|
||||
public string driverPath = string.Format("{0}\\drivers\\netfilter2.sys", Environment.SystemDirectory);
|
||||
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">服务器</param>
|
||||
/// <param name="mode">模式</param>
|
||||
@@ -50,13 +46,8 @@ namespace Netch.Controllers
|
||||
if (!StopServiceAndRestart)
|
||||
MainForm.Instance.StatusText(i18N.Translate("Starting Redirector"));
|
||||
|
||||
if (!File.Exists("bin\\Redirector.exe"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查驱动是否存在
|
||||
if (File.Exists(driverPath))
|
||||
if (File.Exists(_driverPath))
|
||||
{
|
||||
// 生成系统版本
|
||||
var version = $"{Environment.OSVersion.Version.Major.ToString()}.{Environment.OSVersion.Version.Minor.ToString()}";
|
||||
@@ -81,7 +72,7 @@ namespace Netch.Controllers
|
||||
}
|
||||
|
||||
// 检查驱动版本号
|
||||
var SystemfileVerInfo = FileVersionInfo.GetVersionInfo(driverPath);
|
||||
var SystemfileVerInfo = FileVersionInfo.GetVersionInfo(_driverPath);
|
||||
var BinFileVerInfo = FileVersionInfo.GetVersionInfo(string.Format("bin\\{0}", driverName));
|
||||
|
||||
if (!SystemfileVerInfo.FileVersion.Equals(BinFileVerInfo.FileVersion))
|
||||
@@ -96,10 +87,11 @@ namespace Netch.Controllers
|
||||
service.Stop();
|
||||
service.WaitForStatus(ServiceControllerStatus.Stopped);
|
||||
}
|
||||
|
||||
NFAPI.nf_unRegisterDriver("netfilter2");
|
||||
|
||||
//删除老驱动
|
||||
File.Delete(driverPath);
|
||||
File.Delete(_driverPath);
|
||||
if (!InstallDriver())
|
||||
return false;
|
||||
|
||||
@@ -109,16 +101,11 @@ namespace Netch.Controllers
|
||||
{
|
||||
Logging.Info("更新驱动出错");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!InstallDriver())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!InstallDriver()) return false;
|
||||
}
|
||||
|
||||
try
|
||||
@@ -157,11 +144,10 @@ namespace Netch.Controllers
|
||||
processes += proc;
|
||||
processes += ",";
|
||||
}
|
||||
|
||||
processes += "NTT.exe";
|
||||
|
||||
Instance = MainController.GetProcess();
|
||||
Instance.StartInfo.FileName = "bin\\Redirector.exe";
|
||||
Instance.StartInfo.Arguments = "";
|
||||
Instance = MainController.GetProcess("bin\\Redirector.exe");
|
||||
|
||||
if (server.Type != "Socks5")
|
||||
{
|
||||
@@ -177,21 +163,14 @@ namespace Netch.Controllers
|
||||
}
|
||||
|
||||
Instance.StartInfo.Arguments += $"-r {result}:{server.Port} -p \"{processes}\"";
|
||||
if (!string.IsNullOrWhiteSpace(server.Username) && !string.IsNullOrWhiteSpace(server.Password))
|
||||
{
|
||||
Instance.StartInfo.Arguments += $" -username \"{server.Username}\" -password \"{server.Password}\"";
|
||||
}
|
||||
}
|
||||
|
||||
if (File.Exists("logging\\redirector.log"))
|
||||
{
|
||||
File.Delete("logging\\redirector.log");
|
||||
if (!string.IsNullOrWhiteSpace(server.Username) && !string.IsNullOrWhiteSpace(server.Password)) Instance.StartInfo.Arguments += $" -username \"{server.Username}\" -password \"{server.Password}\"";
|
||||
}
|
||||
|
||||
Instance.StartInfo.Arguments += $" -t {Global.Settings.RedirectorTCPPort}";
|
||||
Logging.Info(Instance.StartInfo.Arguments);
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
|
||||
State = State.Starting;
|
||||
Instance.Start();
|
||||
Instance.BeginOutputReadLine();
|
||||
@@ -201,10 +180,7 @@ namespace Netch.Controllers
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
|
||||
if (State == State.Started)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (State == State.Started) return true;
|
||||
}
|
||||
|
||||
Logging.Info("NF 进程启动超时");
|
||||
@@ -212,27 +188,8 @@ namespace Netch.Controllers
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Instance != null && !Instance.HasExited)
|
||||
{
|
||||
Instance.Kill();
|
||||
Instance.WaitForExit();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Info(e.ToString());
|
||||
}
|
||||
}
|
||||
public bool InstallDriver()
|
||||
{
|
||||
|
||||
Logging.Info("安装驱动中");
|
||||
// 生成系统版本
|
||||
var version = $"{Environment.OSVersion.Version.Major.ToString()}.{Environment.OSVersion.Version.Minor.ToString()}";
|
||||
@@ -243,17 +200,17 @@ namespace Netch.Controllers
|
||||
switch (version)
|
||||
{
|
||||
case "10.0":
|
||||
File.Copy("bin\\Win-10.sys", driverPath);
|
||||
File.Copy("bin\\Win-10.sys", _driverPath);
|
||||
Logging.Info("已复制 Win10 驱动");
|
||||
break;
|
||||
case "6.3":
|
||||
case "6.2":
|
||||
File.Copy("bin\\Win-8.sys", driverPath);
|
||||
File.Copy("bin\\Win-8.sys", _driverPath);
|
||||
Logging.Info("已复制 Win8 驱动");
|
||||
break;
|
||||
case "6.1":
|
||||
case "6.0":
|
||||
File.Copy("bin\\Win-7.sys", driverPath);
|
||||
File.Copy("bin\\Win-7.sys", _driverPath);
|
||||
Logging.Info("已复制 Win7 驱动");
|
||||
break;
|
||||
default:
|
||||
@@ -267,6 +224,7 @@ namespace Netch.Controllers
|
||||
Logging.Info(e.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
MainForm.Instance.StatusText(i18N.Translate("Register driver"));
|
||||
// 注册驱动文件
|
||||
var result = NFAPI.nf_registerDriver("netfilter2");
|
||||
@@ -275,51 +233,37 @@ namespace Netch.Controllers
|
||||
Logging.Info($"注册驱动失败,返回值:{result}");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(e.Data))
|
||||
if (!WriteLog(e)) return;
|
||||
if (State == State.Starting)
|
||||
{
|
||||
File.AppendAllText("logging\\redirector.log", string.Format("{0}\r\n", e.Data));
|
||||
|
||||
if (State == State.Starting)
|
||||
if (Instance.HasExited)
|
||||
State = State.Stopped;
|
||||
else if (e.Data.Contains("Started"))
|
||||
State = State.Started;
|
||||
else if (e.Data.Contains("Failed") || e.Data.Contains("Unable")) State = State.Stopped;
|
||||
}
|
||||
else if (State == State.Started)
|
||||
{
|
||||
if (e.Data.StartsWith("[APP][Bandwidth]"))
|
||||
{
|
||||
if (Instance.HasExited)
|
||||
var splited = e.Data.Replace("[APP][Bandwidth]", "").Trim().Split(',');
|
||||
if (splited.Length == 2)
|
||||
{
|
||||
State = State.Stopped;
|
||||
}
|
||||
else if (e.Data.Contains("Started"))
|
||||
{
|
||||
State = State.Started;
|
||||
}
|
||||
else if (e.Data.Contains("Failed") || e.Data.Contains("Unable"))
|
||||
{
|
||||
State = State.Stopped;
|
||||
}
|
||||
}
|
||||
else if (State == State.Started)
|
||||
{
|
||||
if (e.Data.StartsWith("[APP][Bandwidth]"))
|
||||
{
|
||||
var splited = e.Data.Replace("[APP][Bandwidth]", "").Trim().Split(',');
|
||||
if (splited.Length == 2)
|
||||
{
|
||||
var uploadSplited = splited[0].Split(':');
|
||||
var downloadSplited = splited[1].Split(':');
|
||||
var uploadSplited = splited[0].Split(':');
|
||||
var downloadSplited = splited[1].Split(':');
|
||||
|
||||
if (uploadSplited.Length == 2 && downloadSplited.Length == 2)
|
||||
{
|
||||
if (long.TryParse(uploadSplited[1], out var upload) && long.TryParse(downloadSplited[1], out var download))
|
||||
{
|
||||
Task.Run(() => OnBandwidthUpdated(upload, download));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (uploadSplited.Length == 2 && downloadSplited.Length == 2)
|
||||
if (long.TryParse(uploadSplited[1], out var upload) && long.TryParse(downloadSplited[1], out var download))
|
||||
Task.Run(() => OnBandwidthUpdated(upload, download));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,20 +8,16 @@ using Netch.Utils;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class NTTController
|
||||
public class NTTController : Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// 进程实例
|
||||
/// </summary>
|
||||
public Process Instance;
|
||||
public NTTController()
|
||||
{
|
||||
MainName = "NTT";
|
||||
ready = BeforeStartProgress();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前状态
|
||||
/// </summary>
|
||||
public State State = State.Waiting;
|
||||
|
||||
/// <summary>
|
||||
/// 启动NatTypeTester
|
||||
/// 启动NatTypeTester
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public (bool, string, string, string) Start()
|
||||
@@ -30,13 +26,7 @@ namespace Netch.Controllers
|
||||
MainForm.Instance.NatTypeStatusText(i18N.Translate("Starting NatTester"));
|
||||
try
|
||||
{
|
||||
if (!File.Exists("bin\\NTT.exe"))
|
||||
{
|
||||
return (false, null, null, null);
|
||||
}
|
||||
|
||||
Instance = MainController.GetProcess();
|
||||
Instance.StartInfo.FileName = "bin\\NTT.exe";
|
||||
Instance = MainController.GetProcess("bin\\NTT.exe");
|
||||
|
||||
Instance.StartInfo.Arguments = $" {Global.Settings.STUN_Server} {Global.Settings.STUN_Server_Port}";
|
||||
|
||||
@@ -49,7 +39,7 @@ namespace Netch.Controllers
|
||||
Instance.BeginErrorReadLine();
|
||||
Instance.WaitForExit();
|
||||
|
||||
var result = File.ReadAllText("logging\\NTT.log").Split('#');
|
||||
var result = File.ReadAllText($"logging\\{MainName}.log").Split('#');
|
||||
var natType = result[0];
|
||||
var localEnd = result[1];
|
||||
var publicEnd = result[2];
|
||||
@@ -65,36 +55,9 @@ namespace Netch.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Instance != null && !Instance.HasExited)
|
||||
{
|
||||
Instance.Kill();
|
||||
Instance.WaitForExit();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Info(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(e.Data))
|
||||
{
|
||||
if (File.Exists("logging\\NTT.log"))
|
||||
{
|
||||
File.Delete("logging\\NTT.log");
|
||||
}
|
||||
|
||||
File.AppendAllText("logging\\NTT.log", $"{e.Data}\r\n");
|
||||
}
|
||||
WriteLog(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,59 +1,33 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using Netch.Models;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class PrivoxyController
|
||||
public class PrivoxyController : Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// 进程实例
|
||||
/// </summary>
|
||||
public Process Instance;
|
||||
public PrivoxyController()
|
||||
{
|
||||
MainName = "Privoxy";
|
||||
ExtFiles = new[] {"default.conf"};
|
||||
ready = BeforeStartProgress();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">服务器</param>
|
||||
/// <param name="mode">模式</param>
|
||||
/// <returns>是否启动成功</returns>
|
||||
public bool Start(Server server, Mode mode)
|
||||
{
|
||||
foreach (var proc in Process.GetProcessesByName("Privoxy"))
|
||||
{
|
||||
try
|
||||
{
|
||||
proc.Kill();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// 跳过
|
||||
}
|
||||
}
|
||||
|
||||
if (!File.Exists("bin\\Privoxy.exe") || !File.Exists("bin\\default.conf"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (server.Type != "Socks5")
|
||||
{
|
||||
File.WriteAllText("data\\privoxy.conf", File.ReadAllText("bin\\default.conf").Replace("_BIND_PORT_", Global.Settings.HTTPLocalPort.ToString()).Replace("_DEST_PORT_", Global.Settings.Socks5LocalPort.ToString()).Replace("0.0.0.0", Global.Settings.LocalAddress));
|
||||
}
|
||||
else
|
||||
{
|
||||
File.WriteAllText("data\\privoxy.conf", File.ReadAllText("bin\\default.conf").Replace("_BIND_PORT_", Global.Settings.HTTPLocalPort.ToString()).Replace("_DEST_PORT_", server.Port.ToString()).Replace("s 0.0.0.0", $"s {Global.Settings.LocalAddress}").Replace("/ 127.0.0.1", $"/ {server.Hostname}"));
|
||||
}
|
||||
|
||||
|
||||
Instance = new Process
|
||||
{
|
||||
StartInfo =
|
||||
{
|
||||
FileName = string.Format("{0}\\bin\\Privoxy.exe", Directory.GetCurrentDirectory()),
|
||||
FileName = $"{Global.NetchDir}\\bin\\Privoxy.exe",
|
||||
Arguments = "..\\data\\privoxy.conf",
|
||||
WorkingDirectory = string.Format("{0}\\bin", Directory.GetCurrentDirectory()),
|
||||
WorkingDirectory = $"{Global.NetchDir}\\bin",
|
||||
WindowStyle = ProcessWindowStyle.Hidden,
|
||||
UseShellExecute = true,
|
||||
CreateNoWindow = true
|
||||
@@ -63,24 +37,5 @@ namespace Netch.Controllers
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Instance != null && !Instance.HasExited)
|
||||
{
|
||||
Instance.Kill();
|
||||
Instance.WaitForExit();
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// 跳过
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +1,21 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Netch.Forms;
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class SSController
|
||||
public class SSController : ServerClient
|
||||
{
|
||||
/// <summary>
|
||||
/// 进程实例
|
||||
/// </summary>
|
||||
public Process Instance;
|
||||
|
||||
/// <summary>
|
||||
/// 当前状态
|
||||
/// </summary>
|
||||
public State State = State.Waiting;
|
||||
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">服务器</param>
|
||||
/// <param name="mode">模式</param>
|
||||
/// <returns>是否启动成功</returns>
|
||||
public bool Start(Server server, Mode mode)
|
||||
public SSController()
|
||||
{
|
||||
MainForm.Instance.StatusText(i18N.Translate("Starting Shadowsocks"));
|
||||
MainName = "Shadowsocks";
|
||||
ready = BeforeStartProgress();
|
||||
}
|
||||
|
||||
File.Delete("logging\\shadowsocks.log");
|
||||
public override bool Start(Server server, Mode mode)
|
||||
{
|
||||
//从DLL启动Shaowsocks
|
||||
if (Global.Settings.BootShadowsocksFromDLL && (mode.Type == 0 || mode.Type == 1 || mode.Type == 2 || mode.Type == 3))
|
||||
{
|
||||
@@ -46,6 +30,7 @@ namespace Netch.Controllers
|
||||
Logging.Info("DLL SS INFO 设置失败!");
|
||||
return false;
|
||||
}
|
||||
|
||||
Logging.Info("DLL SS INFO 设置成功!");
|
||||
|
||||
if (!NativeMethods.Shadowsocks.Start())
|
||||
@@ -54,31 +39,23 @@ namespace Netch.Controllers
|
||||
Logging.Info("DLL SS 启动失败!");
|
||||
return false;
|
||||
}
|
||||
|
||||
Logging.Info("DLL SS 启动成功!");
|
||||
State = State.Started;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!File.Exists("bin\\Shadowsocks.exe"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Instance = MainController.GetProcess();
|
||||
Instance.StartInfo.FileName = "bin\\Shadowsocks.exe";
|
||||
Instance = MainController.GetProcess("bin\\Shadowsocks.exe");
|
||||
|
||||
#region Instance.Arguments
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(server.Plugin) && !string.IsNullOrWhiteSpace(server.PluginOption))
|
||||
{
|
||||
Instance.StartInfo.Arguments = $"-s {server.Hostname} -p {server.Port} -b {Global.Settings.LocalAddress} -l {Global.Settings.Socks5LocalPort} -m {server.EncryptMethod} -k \"{server.Password}\" -u --plugin {server.Plugin} --plugin-opts \"{server.PluginOption}\"";
|
||||
}
|
||||
else
|
||||
{
|
||||
Instance.StartInfo.Arguments = $"-s {server.Hostname} -p {server.Port} -b {Global.Settings.LocalAddress} -l {Global.Settings.Socks5LocalPort} -m {server.EncryptMethod} -k \"{server.Password}\" -u";
|
||||
}
|
||||
if (mode.BypassChina) Instance.StartInfo.Arguments += " --acl default.acl";
|
||||
|
||||
if (mode.BypassChina)
|
||||
{
|
||||
Instance.StartInfo.Arguments += " --acl default.acl";
|
||||
}
|
||||
#endregion
|
||||
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
@@ -91,10 +68,7 @@ namespace Netch.Controllers
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
|
||||
if (State == State.Started)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (State == State.Started) return true;
|
||||
|
||||
if (State == State.Stopped)
|
||||
{
|
||||
@@ -111,59 +85,25 @@ namespace Netch.Controllers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// SSController 停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
public new void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Global.Settings.BootShadowsocksFromDLL)
|
||||
{
|
||||
NativeMethods.Shadowsocks.Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Instance != null && !Instance.HasExited)
|
||||
{
|
||||
Instance.Kill();
|
||||
Instance.WaitForExit();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Info(e.ToString());
|
||||
}
|
||||
base.Stop();
|
||||
if (Global.Settings.BootShadowsocksFromDLL) NativeMethods.Shadowsocks.Stop();
|
||||
}
|
||||
|
||||
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
public override void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
try
|
||||
if (!WriteLog(e)) return;
|
||||
if (State == State.Starting)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(e.Data))
|
||||
{
|
||||
File.AppendAllText("logging\\shadowsocks.log", $"{e.Data}\r\n");
|
||||
|
||||
if (State == State.Starting)
|
||||
{
|
||||
if (Instance.HasExited)
|
||||
{
|
||||
State = State.Stopped;
|
||||
}
|
||||
else if (e.Data.Contains("listening at"))
|
||||
{
|
||||
State = State.Started;
|
||||
}
|
||||
else if (e.Data.Contains("Invalid config path") || e.Data.Contains("usage") || e.Data.Contains("plugin service exit unexpectedly"))
|
||||
{
|
||||
State = State.Stopped;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ec)
|
||||
{
|
||||
Logging.Info("写入Shadowsocks日志失败" + ec);
|
||||
if (Instance.HasExited)
|
||||
State = State.Stopped;
|
||||
else if (e.Data.Contains("listening at"))
|
||||
State = State.Started;
|
||||
else if (e.Data.Contains("Invalid config path") || e.Data.Contains("usage") || e.Data.Contains("plugin service exit unexpectedly")) State = State.Stopped;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,88 +1,59 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using Netch.Forms;
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class SSRController
|
||||
public class SSRController : ServerClient
|
||||
{
|
||||
/// <summary>
|
||||
/// 进程实例
|
||||
/// </summary>
|
||||
public Process Instance;
|
||||
|
||||
/// <summary>
|
||||
/// 当前状态
|
||||
/// </summary>
|
||||
public State State = State.Waiting;
|
||||
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">服务器</param>
|
||||
/// <param name="mode">模式</param>
|
||||
/// <returns>是否启动成功</returns>
|
||||
public bool Start(Server server, Mode mode)
|
||||
public SSRController()
|
||||
{
|
||||
MainForm.Instance.StatusText(i18N.Translate("Starting ShadowsocksR"));
|
||||
MainName = "ShadowsocksR";
|
||||
ready = BeforeStartProgress();
|
||||
}
|
||||
|
||||
File.Delete("logging\\shadowsocksr.log");
|
||||
|
||||
if (!File.Exists("bin\\ShadowsocksR.exe"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Instance = MainController.GetProcess();
|
||||
public override bool Start(Server server, Mode mode)
|
||||
{
|
||||
Instance = MainController.GetProcess("bin\\ShadowsocksR.exe");
|
||||
Instance.StartInfo.FileName = "bin\\ShadowsocksR.exe";
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
|
||||
#region Instance.Arguments
|
||||
|
||||
Instance.StartInfo.Arguments = $"-s {server.Hostname} -p {server.Port} -k \"{server.Password}\" -m {server.EncryptMethod} -t 120";
|
||||
|
||||
if (!string.IsNullOrEmpty(server.Protocol))
|
||||
{
|
||||
Instance.StartInfo.Arguments += $" -O {server.Protocol}";
|
||||
|
||||
if (!string.IsNullOrEmpty(server.ProtocolParam))
|
||||
{
|
||||
Instance.StartInfo.Arguments += $" -G \"{server.ProtocolParam}\"";
|
||||
}
|
||||
if (!string.IsNullOrEmpty(server.ProtocolParam)) Instance.StartInfo.Arguments += $" -G \"{server.ProtocolParam}\"";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(server.OBFS))
|
||||
{
|
||||
Instance.StartInfo.Arguments += $" -o {server.OBFS}";
|
||||
|
||||
if (!string.IsNullOrEmpty(server.OBFSParam))
|
||||
{
|
||||
Instance.StartInfo.Arguments += $" -g \"{server.OBFSParam}\"";
|
||||
}
|
||||
if (!string.IsNullOrEmpty(server.OBFSParam)) Instance.StartInfo.Arguments += $" -g \"{server.OBFSParam}\"";
|
||||
}
|
||||
|
||||
Instance.StartInfo.Arguments += $" -b {Global.Settings.LocalAddress} -l {Global.Settings.Socks5LocalPort} -u";
|
||||
|
||||
if (mode.BypassChina)
|
||||
{
|
||||
Instance.StartInfo.Arguments += " --acl default.acl";
|
||||
}
|
||||
if (mode.BypassChina) Instance.StartInfo.Arguments += " --acl default.acl";
|
||||
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
#endregion
|
||||
|
||||
State = State.Starting;
|
||||
Instance.Start();
|
||||
Instance.BeginOutputReadLine();
|
||||
Instance.BeginErrorReadLine();
|
||||
|
||||
for (var i = 0; i < 1000; i++)
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
|
||||
if (State == State.Started)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (State == State.Started) return true;
|
||||
|
||||
if (State == State.Stopped)
|
||||
{
|
||||
@@ -98,47 +69,17 @@ namespace Netch.Controllers
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
public override void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
try
|
||||
if (!WriteLog(e)) return;
|
||||
if (State == State.Starting)
|
||||
{
|
||||
if (Instance != null && !Instance.HasExited)
|
||||
{
|
||||
Instance.Kill();
|
||||
Instance.WaitForExit();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Info(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(e.Data))
|
||||
{
|
||||
File.AppendAllText("logging\\shadowsocksr.log", $"{e.Data}\r\n");
|
||||
|
||||
if (State == State.Starting)
|
||||
{
|
||||
if (Instance.HasExited)
|
||||
{
|
||||
State = State.Stopped;
|
||||
}
|
||||
else if (e.Data.Contains("listening at"))
|
||||
{
|
||||
State = State.Started;
|
||||
}
|
||||
else if (e.Data.Contains("Invalid config path") || e.Data.Contains("usage"))
|
||||
{
|
||||
State = State.Stopped;
|
||||
}
|
||||
}
|
||||
if (Instance.HasExited)
|
||||
State = State.Stopped;
|
||||
else if (e.Data.Contains("listening at"))
|
||||
State = State.Started;
|
||||
else if (e.Data.Contains("Invalid config path") || e.Data.Contains("usage")) State = State.Stopped;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
@@ -12,36 +11,33 @@ using Netch.Utils;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class TUNTAPController
|
||||
public class TUNTAPController : Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// 进程实例(tun2socks)
|
||||
/// </summary>
|
||||
public Process Instance;
|
||||
// ByPassLan IP
|
||||
private readonly List<string> BypassLanIPs = new List<string> {"10.0.0.0/8", "172.16.0.0/16", "192.168.0.0/16"};
|
||||
|
||||
/// <summary>
|
||||
/// 当前状态
|
||||
/// 本地 DNS 服务控制器
|
||||
/// </summary>
|
||||
public State State = State.Waiting;
|
||||
public DNSController pDNSController = new DNSController();
|
||||
|
||||
/// <summary>
|
||||
/// 服务器 IP 地址
|
||||
/// </summary>
|
||||
public IPAddress[] ServerAddresses = new IPAddress[0];
|
||||
public Mode SavedMode = new Mode();
|
||||
|
||||
/// <summary>
|
||||
/// 保存传入的规则
|
||||
/// </summary>
|
||||
public Server SavedServer = new Server();
|
||||
public Mode SavedMode = new Mode();
|
||||
|
||||
/// <summary>
|
||||
/// 本地 DNS 服务控制器
|
||||
/// 服务器 IP 地址
|
||||
/// </summary>
|
||||
public DNSController pDNSController = new DNSController();
|
||||
public IPAddress[] ServerAddresses = new IPAddress[0];
|
||||
|
||||
// ByPassLan IP
|
||||
List<string> BypassLanIPs = new List<string> { "10.0.0.0/8", "172.16.0.0/16", "192.168.0.0/16" };
|
||||
public TUNTAPController()
|
||||
{
|
||||
MainName = "tun2socks";
|
||||
ready = BeforeStartProgress();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置 TUNTAP 适配器
|
||||
@@ -52,10 +48,7 @@ namespace Netch.Controllers
|
||||
var destination = Dns.GetHostAddressesAsync(SavedServer.Hostname);
|
||||
if (destination.Wait(1000))
|
||||
{
|
||||
if (destination.Result.Length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (destination.Result.Length == 0) return false;
|
||||
|
||||
ServerAddresses = destination.Result;
|
||||
}
|
||||
@@ -73,12 +66,8 @@ namespace Netch.Controllers
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理模式的绕过中国
|
||||
if (SavedMode.BypassChina)
|
||||
@@ -104,10 +93,7 @@ namespace Netch.Controllers
|
||||
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 (!IPAddress.IsLoopback(address)) NativeMethods.CreateRoute(address.ToString(), int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
}
|
||||
|
||||
Logging.Info("设置绕行规则 → 处理绕过局域网 IP");
|
||||
@@ -117,10 +103,7 @@ namespace Netch.Controllers
|
||||
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 (!IPAddress.IsLoopback(address)) NativeMethods.CreateRoute(address.ToString(), int.Parse(info[1]), Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
}
|
||||
|
||||
if (SavedMode.Type == 2) // 处理仅规则内走直连
|
||||
@@ -146,10 +129,7 @@ namespace Netch.Controllers
|
||||
{
|
||||
State = State.Stopped;
|
||||
|
||||
foreach (var address in ServerAddresses)
|
||||
{
|
||||
NativeMethods.DeleteRoute(address.ToString(), 32, Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
}
|
||||
foreach (var address in ServerAddresses) NativeMethods.DeleteRoute(address.ToString(), 32, Global.Adapter.Gateway.ToString(), Global.Adapter.Index);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -161,12 +141,8 @@ namespace Netch.Controllers
|
||||
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) // 处理仅规则内走代理
|
||||
@@ -177,34 +153,25 @@ namespace Netch.Controllers
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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)
|
||||
{
|
||||
@@ -220,10 +187,7 @@ namespace Netch.Controllers
|
||||
|
||||
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);
|
||||
}
|
||||
if (int.TryParse("32", out var prefix)) NativeMethods.CreateRoute(dns, prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -237,6 +201,7 @@ namespace Netch.Controllers
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -255,12 +220,8 @@ namespace Netch.Controllers
|
||||
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)
|
||||
@@ -270,30 +231,23 @@ namespace Netch.Controllers
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
if (int.TryParse("32", out var prefixr)) NativeMethods.DeleteRoute(nttrAddress.ToString(), prefixr, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
if (Global.Settings.TUNTAP.ProxyDNS)
|
||||
{
|
||||
if (Global.Settings.TUNTAP.UseCustomDNS)
|
||||
@@ -307,17 +261,11 @@ namespace Netch.Controllers
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
if (int.TryParse("32", out var prefix)) NativeMethods.DeleteRoute("1.1.1.1", prefix, Global.Settings.TUNTAP.Gateway, Global.TUNTAP.Index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -327,24 +275,18 @@ namespace Netch.Controllers
|
||||
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 (!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 (!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;
|
||||
@@ -356,63 +298,34 @@ namespace Netch.Controllers
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">配置</param>
|
||||
/// <returns>是否成功</returns>
|
||||
public bool Start(Server server, Mode mode)
|
||||
{
|
||||
MainForm.Instance.StatusText(i18N.Translate("Starting Tap"));
|
||||
foreach (var proc in Process.GetProcessesByName("tun2socks"))
|
||||
{
|
||||
try
|
||||
{
|
||||
proc.Kill();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// 跳过
|
||||
}
|
||||
}
|
||||
|
||||
if (!File.Exists("bin\\tun2socks.exe"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (File.Exists("logging\\tun2socks.log"))
|
||||
{
|
||||
File.Delete("logging\\tun2socks.log");
|
||||
}
|
||||
|
||||
SavedMode = mode;
|
||||
SavedServer = server;
|
||||
|
||||
if (!Configure())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!Configure()) return false;
|
||||
|
||||
Logging.Info("设置绕行规则");
|
||||
SetupBypass();
|
||||
Logging.Info("设置绕行规则完毕");
|
||||
|
||||
Instance = new Process();
|
||||
Instance.StartInfo.WorkingDirectory = string.Format("{0}\\bin", Directory.GetCurrentDirectory());
|
||||
Instance.StartInfo.FileName = string.Format("{0}\\bin\\tun2socks.exe", Directory.GetCurrentDirectory());
|
||||
Instance = MainController.GetProcess("bin\\tun2socks.exe");
|
||||
|
||||
var adapterName = TUNTAP.GetName(Global.TUNTAP.ComponentID);
|
||||
Logging.Info($"tun2sock使用适配器:{adapterName}");
|
||||
|
||||
@@ -436,26 +349,14 @@ namespace Netch.Controllers
|
||||
pDNSController.Start();
|
||||
dns = "127.0.0.1";
|
||||
}
|
||||
if (Global.Settings.TUNTAP.UseFakeDNS)
|
||||
{
|
||||
dns += " -fakeDns";
|
||||
}
|
||||
|
||||
if (Global.Settings.TUNTAP.UseFakeDNS) dns += " -fakeDns";
|
||||
|
||||
if (server.Type == "Socks5")
|
||||
{
|
||||
Instance.StartInfo.Arguments = string.Format("-proxyServer {0}:{1} -tunAddr {2} -tunMask {3} -tunGw {4} -tunDns {5} -tunName \"{6}\"", server.Hostname, server.Port, Global.Settings.TUNTAP.Address, Global.Settings.TUNTAP.Netmask, Global.Settings.TUNTAP.Gateway, dns, adapterName);
|
||||
}
|
||||
else
|
||||
{
|
||||
Instance.StartInfo.Arguments = string.Format("-proxyServer 127.0.0.1:{0} -tunAddr {1} -tunMask {2} -tunGw {3} -tunDns {4} -tunName \"{5}\"", Global.Settings.Socks5LocalPort, Global.Settings.TUNTAP.Address, Global.Settings.TUNTAP.Netmask, Global.Settings.TUNTAP.Gateway, dns, adapterName);
|
||||
}
|
||||
|
||||
Instance.StartInfo.CreateNoWindow = true;
|
||||
Instance.StartInfo.RedirectStandardError = true;
|
||||
Instance.StartInfo.RedirectStandardInput = true;
|
||||
Instance.StartInfo.RedirectStandardOutput = true;
|
||||
Instance.StartInfo.UseShellExecute = false;
|
||||
Instance.EnableRaisingEvents = true;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
|
||||
@@ -471,10 +372,7 @@ namespace Netch.Controllers
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
|
||||
if (State == State.Started)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (State == State.Started) return true;
|
||||
|
||||
if (State == State.Stopped)
|
||||
{
|
||||
@@ -487,46 +385,24 @@ namespace Netch.Controllers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// TUN/TAP停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
public new void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Instance != null && !Instance.HasExited)
|
||||
{
|
||||
Instance.Kill();
|
||||
}
|
||||
|
||||
//pDNSController.Stop();
|
||||
//修复点击停止按钮后再启动,DNS服务没监听的BUG
|
||||
ClearBypass();
|
||||
pDNSController.Stop();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Info(e.ToString());
|
||||
}
|
||||
base.Stop();
|
||||
ClearBypass();
|
||||
pDNSController.Stop();
|
||||
}
|
||||
|
||||
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(e.Data))
|
||||
if (!WriteLog(e)) return;
|
||||
if (State == State.Starting)
|
||||
{
|
||||
File.AppendAllText("logging\\tun2socks.log", string.Format("{0}\r\n", e.Data.Trim()));
|
||||
|
||||
if (State == State.Starting)
|
||||
{
|
||||
if (e.Data.Contains("Running"))
|
||||
{
|
||||
State = State.Started;
|
||||
}
|
||||
else if (e.Data.Contains("failed") || e.Data.Contains("invalid vconfig file"))
|
||||
{
|
||||
State = State.Stopped;
|
||||
}
|
||||
}
|
||||
if (e.Data.Contains("Running"))
|
||||
State = State.Started;
|
||||
else if (e.Data.Contains("failed") || e.Data.Contains("invalid vconfig file")) State = State.Stopped;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
@@ -10,34 +9,18 @@ using Newtonsoft.Json;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class TrojanController
|
||||
public class TrojanController : ServerClient
|
||||
{
|
||||
/// <summary>
|
||||
/// 进程实例
|
||||
/// </summary>
|
||||
public Process Instance;
|
||||
public TrojanController()
|
||||
{
|
||||
MainName = "Trojan";
|
||||
ready = BeforeStartProgress();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前状态
|
||||
/// </summary>
|
||||
public State State = State.Waiting;
|
||||
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">服务器</param>
|
||||
/// <param name="mode">模式</param>
|
||||
/// <returns>是否启动成功</returns>
|
||||
public bool Start(Server server, Mode mode)
|
||||
public override bool Start(Server server, Mode mode)
|
||||
{
|
||||
MainForm.Instance.StatusText(i18N.Translate("Starting Trojan"));
|
||||
|
||||
File.Delete("logging\\trojan.log");
|
||||
if (!File.Exists("bin\\Trojan.exe"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
File.WriteAllText("data\\last.json", JsonConvert.SerializeObject(new Trojan
|
||||
{
|
||||
local_addr = Global.Settings.LocalAddress,
|
||||
@@ -50,8 +33,7 @@ namespace Netch.Controllers
|
||||
}
|
||||
}));
|
||||
|
||||
Instance = MainController.GetProcess();
|
||||
Instance.StartInfo.FileName = "bin\\Trojan.exe";
|
||||
Instance = MainController.GetProcess("bin\\Trojan.exe");
|
||||
Instance.StartInfo.Arguments = "-c ..\\data\\last.json";
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
Instance.ErrorDataReceived += OnOutputDataReceived;
|
||||
@@ -64,10 +46,7 @@ namespace Netch.Controllers
|
||||
{
|
||||
Thread.Sleep(10);
|
||||
|
||||
if (State == State.Started)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (State == State.Started) return true;
|
||||
|
||||
if (State == State.Stopped)
|
||||
{
|
||||
@@ -83,47 +62,17 @@ namespace Netch.Controllers
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
public override void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
try
|
||||
if (!WriteLog(e)) return;
|
||||
if (State == State.Starting)
|
||||
{
|
||||
if (Instance != null && !Instance.HasExited)
|
||||
{
|
||||
Instance.Kill();
|
||||
Instance.WaitForExit();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Info(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(e.Data))
|
||||
{
|
||||
File.AppendAllText("logging\\trojan.log", $"{e.Data}\r\n");
|
||||
|
||||
if (State == State.Starting)
|
||||
{
|
||||
if (Instance.HasExited)
|
||||
{
|
||||
State = State.Stopped;
|
||||
}
|
||||
else if (e.Data.Contains("started"))
|
||||
{
|
||||
State = State.Started;
|
||||
}
|
||||
else if (e.Data.Contains("exiting"))
|
||||
{
|
||||
State = State.Stopped;
|
||||
}
|
||||
}
|
||||
if (Instance.HasExited)
|
||||
State = State.Stopped;
|
||||
else if (e.Data.Contains("started"))
|
||||
State = State.Started;
|
||||
else if (e.Data.Contains("exiting")) State = State.Stopped;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,10 @@ namespace Netch.Controllers
|
||||
public const string Owner = @"NetchX";
|
||||
public const string Repo = @"Netch";
|
||||
|
||||
public const string Name = @"Netch";
|
||||
public const string Copyright = @"Copyright © 2019 - 2020";
|
||||
public const string Version = @"1.4.11";
|
||||
|
||||
public string LatestVersionNumber;
|
||||
public string LatestVersionUrl;
|
||||
|
||||
@@ -24,10 +28,6 @@ namespace Netch.Controllers
|
||||
public event EventHandler NewVersionFoundFailed;
|
||||
public event EventHandler NewVersionNotFound;
|
||||
|
||||
public const string Name = @"Netch";
|
||||
public const string Copyright = @"Copyright © 2019 - 2020";
|
||||
public const string Version = @"1.4.11";
|
||||
|
||||
public async void Check(bool notifyNoFound, bool isPreRelease)
|
||||
{
|
||||
try
|
||||
@@ -48,19 +48,13 @@ namespace Netch.Controllers
|
||||
else
|
||||
{
|
||||
LatestVersionNumber = latestRelease.tag_name;
|
||||
if (notifyNoFound)
|
||||
{
|
||||
NewVersionNotFound?.Invoke(this, new EventArgs());
|
||||
}
|
||||
if (notifyNoFound) NewVersionNotFound?.Invoke(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine(e.Message);
|
||||
if (notifyNoFound)
|
||||
{
|
||||
NewVersionFoundFailed?.Invoke(this, new EventArgs());
|
||||
}
|
||||
if (notifyNoFound) NewVersionFoundFailed?.Invoke(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,4 +78,4 @@ namespace Netch.Controllers
|
||||
return resultStr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Netch.Forms;
|
||||
using Netch.Models;
|
||||
using Netch.Utils;
|
||||
using Newtonsoft.Json;
|
||||
@@ -11,32 +9,16 @@ using VMess = Netch.Models.Information.VMess;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class VMessController
|
||||
public class VMessController : ServerClient
|
||||
{
|
||||
/// <summary>
|
||||
/// 进程实例
|
||||
/// </summary>
|
||||
public Process Instance;
|
||||
|
||||
/// <summary>
|
||||
/// 当前状态
|
||||
/// </summary>
|
||||
public State State = State.Waiting;
|
||||
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
/// <param name="server">服务器</param>
|
||||
/// <param name="mode">模式</param>
|
||||
/// <returns>是否启动成功</returns>
|
||||
public bool Start(Server server, Mode mode)
|
||||
public VMessController()
|
||||
{
|
||||
MainForm.Instance.StatusText(i18N.Translate("Starting V2ray"));
|
||||
if (!File.Exists("bin\\v2ray.exe") || !File.Exists("bin\\v2ctl.exe"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
MainName = "v2ray";
|
||||
ready = BeforeStartProgress();
|
||||
}
|
||||
|
||||
public override bool Start(Server server, Mode mode)
|
||||
{
|
||||
File.WriteAllText("data\\last.json", JsonConvert.SerializeObject(new VMess.Config
|
||||
{
|
||||
inbounds = new List<VMess.Inbounds>
|
||||
@@ -76,50 +58,60 @@ namespace Netch.Controllers
|
||||
{
|
||||
network = server.TransferProtocol,
|
||||
security = server.TLSSecure ? "tls" : "",
|
||||
wsSettings = server.TransferProtocol == "ws" ? new VMess.WebSocketSettings
|
||||
{
|
||||
path = server.Path == "" ? "/" : server.Path,
|
||||
headers = new VMess.WSHeaders
|
||||
wsSettings = server.TransferProtocol == "ws"
|
||||
? new VMess.WebSocketSettings
|
||||
{
|
||||
Host = server.Host == "" ? server.Hostname : server.Host
|
||||
}
|
||||
} : null,
|
||||
tcpSettings = server.FakeType == "http" ? new VMess.TCPSettings
|
||||
{
|
||||
header = new VMess.TCPHeaders
|
||||
{
|
||||
type = server.FakeType,
|
||||
request = new VMess.TCPRequest
|
||||
path = server.Path == "" ? "/" : server.Path,
|
||||
headers = new VMess.WSHeaders
|
||||
{
|
||||
path = server.Path == "" ? "/" : server.Path,
|
||||
headers = new VMess.TCPRequestHeaders
|
||||
Host = server.Host == "" ? server.Hostname : server.Host
|
||||
}
|
||||
}
|
||||
: null,
|
||||
tcpSettings = server.FakeType == "http"
|
||||
? new VMess.TCPSettings
|
||||
{
|
||||
header = new VMess.TCPHeaders
|
||||
{
|
||||
type = server.FakeType,
|
||||
request = new VMess.TCPRequest
|
||||
{
|
||||
Host = server.Host == "" ? server.Hostname : server.Host
|
||||
path = server.Path == "" ? "/" : server.Path,
|
||||
headers = new VMess.TCPRequestHeaders
|
||||
{
|
||||
Host = server.Host == "" ? server.Hostname : server.Host
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} : null,
|
||||
kcpSettings = server.TransferProtocol == "kcp" ? new VMess.KCPSettings
|
||||
{
|
||||
header = new VMess.TCPHeaders
|
||||
: null,
|
||||
kcpSettings = server.TransferProtocol == "kcp"
|
||||
? new VMess.KCPSettings
|
||||
{
|
||||
type = server.FakeType
|
||||
header = new VMess.TCPHeaders
|
||||
{
|
||||
type = server.FakeType
|
||||
}
|
||||
}
|
||||
} : null,
|
||||
quicSettings = server.TransferProtocol == "quic" ? new VMess.QUICSettings
|
||||
{
|
||||
security = server.QUICSecure,
|
||||
key = server.QUICSecret,
|
||||
header = new VMess.TCPHeaders
|
||||
: null,
|
||||
quicSettings = server.TransferProtocol == "quic"
|
||||
? new VMess.QUICSettings
|
||||
{
|
||||
type = server.FakeType
|
||||
security = server.QUICSecure,
|
||||
key = server.QUICSecret,
|
||||
header = new VMess.TCPHeaders
|
||||
{
|
||||
type = server.FakeType
|
||||
}
|
||||
}
|
||||
} : null,
|
||||
httpSettings = server.TransferProtocol == "h2" ? new VMess.HTTPSettings
|
||||
{
|
||||
host = server.Host == "" ? server.Hostname : server.Host,
|
||||
path = server.Path == "" ? "/" : server.Path
|
||||
} : null,
|
||||
: null,
|
||||
httpSettings = server.TransferProtocol == "h2"
|
||||
? new VMess.HTTPSettings
|
||||
{
|
||||
host = server.Host == "" ? server.Hostname : server.Host,
|
||||
path = server.Path == "" ? "/" : server.Path
|
||||
}
|
||||
: null,
|
||||
tlsSettings = new VMess.TLSSettings
|
||||
{
|
||||
allowInsecure = true,
|
||||
@@ -131,58 +123,51 @@ namespace Netch.Controllers
|
||||
enabled = server.UseMux
|
||||
}
|
||||
},
|
||||
(mode.Type==0||mode.Type==1||mode.Type==2) ? new VMess.Outbounds
|
||||
{
|
||||
tag = "TUNTAP",
|
||||
protocol = "freedom"
|
||||
}: new VMess.Outbounds
|
||||
{
|
||||
tag = "direct",
|
||||
protocol = "freedom"
|
||||
}
|
||||
mode.Type == 0 || mode.Type == 1 || mode.Type == 2
|
||||
? new VMess.Outbounds
|
||||
{
|
||||
tag = "TUNTAP",
|
||||
protocol = "freedom"
|
||||
}
|
||||
: new VMess.Outbounds
|
||||
{
|
||||
tag = "direct",
|
||||
protocol = "freedom"
|
||||
}
|
||||
},
|
||||
routing = new VMess.Routing
|
||||
{
|
||||
rules = new List<VMess.RoutingRules>
|
||||
{
|
||||
mode.BypassChina ? new VMess.RoutingRules
|
||||
{
|
||||
type = "field",
|
||||
ip = new List<string>
|
||||
mode.BypassChina
|
||||
? new VMess.RoutingRules
|
||||
{
|
||||
"geoip:cn",
|
||||
"geoip:private"
|
||||
|
||||
},
|
||||
domain = new List<string>
|
||||
type = "field",
|
||||
ip = new List<string>
|
||||
{
|
||||
"geoip:cn",
|
||||
"geoip:private"
|
||||
},
|
||||
domain = new List<string>
|
||||
{
|
||||
"geosite:cn"
|
||||
},
|
||||
outboundTag = "direct"
|
||||
}
|
||||
: new VMess.RoutingRules
|
||||
{
|
||||
"geosite:cn"
|
||||
},
|
||||
outboundTag = "direct"
|
||||
} : new VMess.RoutingRules
|
||||
{
|
||||
type = "field",
|
||||
ip = new List<string>
|
||||
{
|
||||
"geoip:private"
|
||||
},
|
||||
outboundTag = "direct"
|
||||
}
|
||||
type = "field",
|
||||
ip = new List<string>
|
||||
{
|
||||
"geoip:private"
|
||||
},
|
||||
outboundTag = "direct"
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
// 清理上一次的日志文件,防止淤积占用磁盘空间
|
||||
if (Directory.Exists("logging"))
|
||||
{
|
||||
if (File.Exists("logging\\v2ray.log"))
|
||||
{
|
||||
File.Delete("logging\\v2ray.log");
|
||||
}
|
||||
}
|
||||
|
||||
Instance = MainController.GetProcess();
|
||||
Instance.StartInfo.FileName = "bin\\v2ray.exe";
|
||||
Instance = MainController.GetProcess("bin\\v2ray.exe");
|
||||
Instance.StartInfo.Arguments = "-config ..\\data\\last.json";
|
||||
|
||||
Instance.OutputDataReceived += OnOutputDataReceived;
|
||||
@@ -198,10 +183,8 @@ namespace Netch.Controllers
|
||||
|
||||
if (State == State.Started)
|
||||
{
|
||||
if (File.Exists("data\\last.json"))
|
||||
{
|
||||
File.Delete("data\\last.json");
|
||||
}
|
||||
if (File.Exists("data\\last.json")) File.Delete("data\\last.json");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -219,47 +202,17 @@ namespace Netch.Controllers
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
public override void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
try
|
||||
if (!WriteLog(e)) return;
|
||||
if (State == State.Starting)
|
||||
{
|
||||
if (Instance != null && !Instance.HasExited)
|
||||
{
|
||||
Instance.Kill();
|
||||
Instance.WaitForExit();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logging.Info(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public void OnOutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(e.Data))
|
||||
{
|
||||
File.AppendAllText("logging\\v2ray.log", $"{e.Data}\r\n");
|
||||
|
||||
if (State == State.Starting)
|
||||
{
|
||||
if (Instance.HasExited)
|
||||
{
|
||||
State = State.Stopped;
|
||||
}
|
||||
else if (e.Data.Contains("started"))
|
||||
{
|
||||
State = State.Started;
|
||||
}
|
||||
else if (e.Data.Contains("config file not readable") || e.Data.Contains("failed to"))
|
||||
{
|
||||
State = State.Stopped;
|
||||
}
|
||||
}
|
||||
if (Instance.HasExited)
|
||||
State = State.Stopped;
|
||||
else if (e.Data.Contains("started"))
|
||||
State = State.Started;
|
||||
else if (e.Data.Contains("config file not readable") || e.Data.Contains("failed to")) State = State.Stopped;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -151,7 +151,7 @@ namespace Netch.Forms
|
||||
else
|
||||
{
|
||||
UpdateStatus(State.Stopped);
|
||||
StatusText(i18N.Translate("Start Failed"));
|
||||
StatusText(i18N.Translate("Start failed"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
|
||||
@@ -6,6 +7,14 @@ namespace Netch
|
||||
{
|
||||
public static class Global
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 换行
|
||||
/// </summary>
|
||||
public static string EOF = "\r\n";
|
||||
|
||||
public static readonly string NetchDir = (AppDomain.CurrentDomain.BaseDirectory).TrimEnd();
|
||||
|
||||
/// <summary>
|
||||
/// 主窗体
|
||||
/// </summary>
|
||||
|
||||
@@ -16,10 +16,8 @@
|
||||
"Started": "已启动",
|
||||
"Stopping": "正在停止中",
|
||||
"Stopped": "已停止",
|
||||
"Starting Shadowsocks": "正在启动 Shadowsocks",
|
||||
"Starting ShadowsocksR": "正在启动 ShadowsocksR",
|
||||
"Starting V2ray": "正在启动 V2Ray",
|
||||
"Starting Trojan": "正在启动 Trojan",
|
||||
"Starting ": "正在启动 ",
|
||||
"v2ray": "V2Ray",
|
||||
"Starting Tap": "正在启动 TUN/TAP",
|
||||
"Starting NatTester": "正在启动 NAT 测试",
|
||||
"Starting LocalDns service": "正在启动本地 DNS 服务",
|
||||
|
||||
@@ -58,21 +58,10 @@ namespace Netch.Utils
|
||||
{
|
||||
processList.Add(Process.GetCurrentProcess().Id);
|
||||
}
|
||||
else if (server.Type.Equals("SS") && mainController.pSSController != null)
|
||||
else if (mainController.pServerClientController != null)
|
||||
{
|
||||
processList.Add(mainController.pSSController.Instance.Id);
|
||||
}
|
||||
else if (server.Type.Equals("SSR") && mainController.pSSRController != null)
|
||||
{
|
||||
processList.Add(mainController.pSSRController.Instance.Id);
|
||||
}
|
||||
else if (server.Type.Equals("VMess") && mainController.pVMessController != null)
|
||||
{
|
||||
processList.Add(mainController.pVMessController.Instance.Id);
|
||||
}
|
||||
else if (server.Type.Equals("TR") && mainController.pTrojanController != null)
|
||||
{
|
||||
processList.Add(mainController.pTrojanController.Instance.Id);
|
||||
// mainController.pServerClientController.Instance
|
||||
processList.Add(mainController.pServerClientController.Instance.Id);
|
||||
}
|
||||
else if (mainController.pTUNTAPController != null)
|
||||
{
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace Netch.Utils
|
||||
/// </summary>
|
||||
public static void AddNetchFwRules()
|
||||
{
|
||||
if (GetFwRulePath(_netch).StartsWith(AppDomain.CurrentDomain.BaseDirectory) && GetFwRulesNumber(_netch) >= ProgramPath.Length) return;
|
||||
if (GetFwRulePath(_netch).StartsWith(Global.NetchDir) && GetFwRulesNumber(_netch) >= ProgramPath.Length) return;
|
||||
RemoveNetchFwRules();
|
||||
foreach (var p in ProgramPath)
|
||||
{
|
||||
|
||||
@@ -5,10 +5,6 @@ namespace Netch.Utils
|
||||
{
|
||||
public static class Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// 换行
|
||||
/// </summary>
|
||||
public static string EOF = "\r\n";
|
||||
|
||||
/// <summary>
|
||||
/// 信息
|
||||
@@ -16,7 +12,7 @@ namespace Netch.Utils
|
||||
/// <param name="text">内容</param>
|
||||
public static void Info(string text)
|
||||
{
|
||||
File.AppendAllText("logging\\application.log", string.Format("[{0}] {1}{2}", DateTime.Now, text, EOF));
|
||||
File.AppendAllText("logging\\application.log", $@"[{DateTime.Now}] {text}{Global.EOF}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user