Compare commits

..

19 Commits

Author SHA1 Message Date
ChsBuffer
e2bcdc8840 Bump version to 1.8.3-Beta4 2021-03-26 15:00:22 +08:00
ChsBuffer
4202c8ac5a Refactor Add Guard.Keywords setter 2021-03-26 13:03:37 +08:00
ChsBuffer
db765d60f0 Fix possible null reference warning 2021-03-26 12:02:34 +08:00
ChsBuffer
28c248ea70 Fix Updater.cs import 2021-03-26 10:35:25 +08:00
ChsBuffer
f818c444a4 Refactor create tun2socks arguments and setup route table after tun2socks started 2021-03-26 10:29:51 +08:00
ChsBuffer
d260afd49b Feat: -forceUpdate Parameter 2021-03-26 10:29:50 +08:00
ChsBuffer
66bfe39674 Improve Updater stability 2021-03-26 10:29:50 +08:00
AmazingDM
95d1b039cd update binaries 2021-03-26 10:20:30 +08:00
ChsBuffer
b2a7d4fd59 upgrade nuget packages 2021-03-26 10:20:29 +08:00
ChsBuffer
ec6b9a2c18 Fix PostBuild call bat 2021-03-26 10:20:29 +08:00
ChsBuffer
dcb90ccdcd Refactor: split Global.cs 2021-03-25 12:21:42 +08:00
ChsBuffer
5da5daa112 extract Interop.nfapinet project 2021-03-24 23:12:15 +08:00
ChsBuffer
5d5ee40cd6 Migrate to HMBSbige.SingleInstance 2021-03-24 11:32:26 +08:00
ChsBuffer
32d3e97288 Update TryReleaseUsedTcpPort 2021-03-24 11:32:26 +08:00
ChsBuffer
452c5ec67c Extract LogStopwatch class 2021-03-24 11:32:25 +08:00
AmazingDM
9d2fd2cce3 Update UpdateChecker.cs 2021-03-24 10:30:10 +08:00
AmazingDM
5a3295d10c RDR Memory optimization 2021-03-23 22:28:23 +08:00
ChsBuffer
8269948288 Update GetProcessByUsedTcpPort (Fix #591) 2021-03-23 16:14:34 +08:00
ChsBuffer
8e545fc05f Remove Reload Mode MenuToolStrip 2021-03-23 13:41:43 +08:00
30 changed files with 413 additions and 239 deletions

View File

@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net48</TargetFramework>
<LangVersion>latest</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
</Project>

View File

@@ -2,6 +2,8 @@
using System;
using System.Runtime.InteropServices;
// ReSharper disable All
namespace nfapinet
{
public enum NF_STATUS

View File

@@ -9,6 +9,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SearchComboBox", "SearchCom
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest", "UnitTest\UnitTest.csproj", "{53397641-35CA-4336-8E22-2CE12EF476AC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interop.nfapinet", "Interop.nfapinet\Interop.nfapinet.csproj", "{2C968ADF-4822-46A9-A7D9-D05A61CB14DE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -26,6 +28,10 @@ Global
{53397641-35CA-4336-8E22-2CE12EF476AC}.Debug|x64.ActiveCfg = Debug|x64
{53397641-35CA-4336-8E22-2CE12EF476AC}.Debug|x64.Build.0 = Debug|x64
{53397641-35CA-4336-8E22-2CE12EF476AC}.Release|x64.ActiveCfg = Release|x64
{2C968ADF-4822-46A9-A7D9-D05A61CB14DE}.Debug|x64.ActiveCfg = Debug|Any CPU
{2C968ADF-4822-46A9-A7D9-D05A61CB14DE}.Debug|x64.Build.0 = Debug|Any CPU
{2C968ADF-4822-46A9-A7D9-D05A61CB14DE}.Release|x64.ActiveCfg = Release|Any CPU
{2C968ADF-4822-46A9-A7D9-D05A61CB14DE}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

16
Netch/Constants.cs Normal file
View File

@@ -0,0 +1,16 @@
namespace Netch
{
public static class Constants
{
public const string EOF = "\r\n";
public const string UserACL = "data\\user.acl";
public const string BuiltinACL = "bin\\default.acl";
public static class Parameter
{
public const string Show = "-show";
public const string ForceUpdate = "-forceUpdate";
public const string Console = "-console";
}
}
}

View File

@@ -30,12 +30,12 @@ namespace Netch.Controllers
/// <summary>
/// 成功启动关键词
/// </summary>
protected virtual IEnumerable<string> StartedKeywords { get; } = new List<string>();
protected virtual IEnumerable<string> StartedKeywords { get; set; } = new List<string>();
/// <summary>
/// 启动失败关键词
/// </summary>
protected virtual IEnumerable<string> StoppedKeywords { get; } = new List<string>();
protected virtual IEnumerable<string> StoppedKeywords { get; set; } = new List<string>();
public abstract string Name { get; }

View File

@@ -193,16 +193,25 @@ namespace Netch.Controllers
{
foreach (var p in PortHelper.GetProcessByUsedTcpPort(port))
{
if (p.MainModule!.FileName.StartsWith(Global.NetchDir))
string fileName;
try
{
fileName = p.MainModule!.FileName;
}
catch (Exception e)
{
Logging.Warning(e.ToString());
continue;
}
if (fileName.StartsWith(Global.NetchDir))
{
p.Kill();
p.WaitForExit();
}
else
{
throw new MessageException(i18N.TranslateFormat("The {0} port is used by {1}.",
$"{portName} ({port})",
$"({p.Id}){p.MainModule.FileName}"));
throw new MessageException(i18N.TranslateFormat("The {0} port is used by {1}.", $"{portName} ({port})", $"({p.Id}){fileName}"));
}
}

View File

@@ -17,7 +17,7 @@ namespace Netch.Controllers
public override string MainFile { get; protected set; } = "pcap2socks.exe";
protected override IEnumerable<string> StartedKeywords { get; } = new[] {"└"};
protected override IEnumerable<string> StartedKeywords { get; set; } = new[] {"└"};
private readonly OutboundAdapter _outbound = new();

View File

@@ -26,9 +26,9 @@ namespace Netch.Controllers
/// </summary>
public DNSController DNSController = new();
protected override IEnumerable<string> StartedKeywords { get; } = new[] {"Running"};
protected override IEnumerable<string> StartedKeywords { get; set; } = new[] {"Running"};
protected override IEnumerable<string> StoppedKeywords { get; } = new[] {"failed", "invalid vconfig file"};
protected override IEnumerable<string> StoppedKeywords { get; set; } = new[] {"failed", "invalid vconfig file"};
public override string MainFile { get; protected set; } = "tun2socks.exe";
@@ -61,23 +61,42 @@ namespace Netch.Controllers
dns = new List<string> {"127.0.0.1"};
}
SetupRouteTable(mode);
var parameter = new Tun2SocksParameter
{
tunAddr = Global.Settings.TUNTAP.Address,
tunMask = Global.Settings.TUNTAP.Netmask,
tunGw = Global.Settings.TUNTAP.Gateway,
tunDns = DnsUtils.Join(dns),
tunName = TUNTAP.GetName(_tap.ComponentID),
fakeDns = Global.Settings.TUNTAP.UseFakeDNS && Flags.SupportFakeDns
};
Global.MainForm.StatusText(i18N.TranslateFormat("Starting {0}", Name));
var argument = new StringBuilder();
if (server is Socks5 socks5 && !socks5.Auth())
argument.Append($"-proxyServer {server.AutoResolveHostname()}:{server.Port} ");
parameter.proxyServer = $"{server.AutoResolveHostname()}:{server.Port}";
else
argument.Append($"-proxyServer 127.0.0.1:{Global.Settings.Socks5LocalPort} ");
parameter.proxyServer = $"127.0.0.1:{Global.Settings.Socks5LocalPort}";
argument.Append(
$"-tunAddr {Global.Settings.TUNTAP.Address} -tunMask {Global.Settings.TUNTAP.Netmask} -tunGw {Global.Settings.TUNTAP.Gateway} -tunDns {DnsUtils.Join(dns)} -tunName \"{TUNTAP.GetName(_tap.ComponentID)}\" ");
StartInstanceAuto(parameter.ToString(), ProcessPriorityClass.RealTime);
if (Global.Settings.TUNTAP.UseFakeDNS && Global.Flags.SupportFakeDns)
argument.Append("-fakeDns ");
SetupRouteTable(mode);
}
StartInstanceAuto(argument.ToString(), ProcessPriorityClass.RealTime);
[Verb]
public class Tun2SocksParameter : ParameterBase
{
public string proxyServer { get; set; }
public string tunAddr { get; set; }
public string tunMask { get; set; }
public string tunGw { get; set; }
public string tunDns { get; set; }
public string tunName { get; set; }
public bool fakeDns { get; set; }
}
/// <summary>
@@ -127,14 +146,7 @@ namespace Netch.Controllers
// 绕过规则 IP
// 将 TUN/TAP 网卡权重放到最高
Process.Start(new ProcessStartInfo
{
FileName = "netsh",
Arguments = $"interface ip set interface {_tap.Index} metric=0",
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = true,
CreateNoWindow = true
});
SetInterface(RouteType.TUNTAP, 0);
Logging.Info("绕行 → 规则 IP");
RouteAction(Action.Create, mode.FullRule, RouteType.Outbound);
@@ -157,6 +169,29 @@ namespace Netch.Controllers
}
}
private void SetInterface(RouteType routeType, int? metric = null)
{
IAdapter adapter = routeType switch
{
RouteType.Outbound => _outbound,
RouteType.TUNTAP => _tap,
_ => throw new ArgumentOutOfRangeException(nameof(routeType), routeType, null)
};
var arguments = $"interface ip set interface {adapter.Index} ";
if (metric != null)
arguments += $"metric={metric} ";
Process.Start(new ProcessStartInfo
{
FileName = "netsh",
Arguments = arguments,
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = true,
CreateNoWindow = true
});
}
/// <summary>
/// 清除绕行规则
/// </summary>

View File

@@ -20,7 +20,7 @@ namespace Netch.Controllers
public const string Copyright = @"Copyright © 2019 - 2021";
public const string AssemblyVersion = @"1.8.3";
private const string Suffix = @"Beta2";
private const string Suffix = @"Beta4";
public static readonly string Version = $"{AssemblyVersion}{(string.IsNullOrEmpty(Suffix) ? "" : $"-{Suffix}")}";

16
Netch/Flags.cs Normal file
View File

@@ -0,0 +1,16 @@
using System;
using Netch.Controllers;
namespace Netch
{
public static class Flags
{
public static readonly bool IsWindows10Upper = Environment.OSVersion.Version.Major >= 10;
private static readonly Lazy<bool> LazySupportFakeDns = new(() => new TUNTAPController().TestFakeDNS());
public static bool SupportFakeDns => LazySupportFakeDns.Value;
public static bool AlwaysShowNewVersionFound { get; set; }
}
}

View File

@@ -29,14 +29,12 @@
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
this.MenuStrip = new System.Windows.Forms.MenuStrip();
this.ServerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.ImportServersFromClipboardToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.ModeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.CreateProcessModeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.CreateRouteTableRuleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.ReloadModesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.SubscribeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.ManageSubscribeLinksToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.UpdateServersFromSubscribeLinksToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@@ -95,13 +93,13 @@
this.ConfigurationGroupBox.SuspendLayout();
this.configLayoutPanel.SuspendLayout();
this.tableLayoutPanel2.SuspendLayout();
((System.ComponentModel.ISupportInitialize) (this.EditServerPictureBox)).BeginInit();
((System.ComponentModel.ISupportInitialize) (this.CopyLinkPictureBox)).BeginInit();
((System.ComponentModel.ISupportInitialize) (this.DeleteServerPictureBox)).BeginInit();
((System.ComponentModel.ISupportInitialize) (this.SpeedPictureBox)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.EditServerPictureBox)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.CopyLinkPictureBox)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.DeleteServerPictureBox)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.SpeedPictureBox)).BeginInit();
this.tableLayoutPanel3.SuspendLayout();
((System.ComponentModel.ISupportInitialize) (this.EditModePictureBox)).BeginInit();
((System.ComponentModel.ISupportInitialize) (this.DeleteModePictureBox)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.EditModePictureBox)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.DeleteModePictureBox)).BeginInit();
this.StatusStrip.SuspendLayout();
this.NotifyMenu.SuspendLayout();
this.ProfileGroupBox.SuspendLayout();
@@ -113,10 +111,16 @@
//
this.MenuStrip.BackColor = System.Drawing.SystemColors.Control;
this.MenuStrip.ImageScalingSize = new System.Drawing.Size(20, 20);
this.MenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[]
{
this.ServerToolStripMenuItem, this.ModeToolStripMenuItem, this.SubscribeToolStripMenuItem, this.OptionsToolStripMenuItem, this.HelpToolStripMenuItem, this.exitToolStripMenuItem, this.AboutToolStripButton, this.NewVersionLabel, this.VersionLabel
});
this.MenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.ServerToolStripMenuItem,
this.ModeToolStripMenuItem,
this.SubscribeToolStripMenuItem,
this.OptionsToolStripMenuItem,
this.HelpToolStripMenuItem,
this.exitToolStripMenuItem,
this.AboutToolStripButton,
this.NewVersionLabel,
this.VersionLabel});
this.MenuStrip.Location = new System.Drawing.Point(0, 0);
this.MenuStrip.Name = "MenuStrip";
this.MenuStrip.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional;
@@ -125,10 +129,8 @@
//
// ServerToolStripMenuItem
//
this.ServerToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[]
{
this.ImportServersFromClipboardToolStripMenuItem
});
this.ServerToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.ImportServersFromClipboardToolStripMenuItem});
this.ServerToolStripMenuItem.Margin = new System.Windows.Forms.Padding(3, 0, 0, 1);
this.ServerToolStripMenuItem.Name = "ServerToolStripMenuItem";
this.ServerToolStripMenuItem.Size = new System.Drawing.Size(57, 21);
@@ -143,7 +145,9 @@
//
// ModeToolStripMenuItem
//
this.ModeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {this.CreateProcessModeToolStripMenuItem, this.CreateRouteTableRuleToolStripMenuItem, this.ReloadModesToolStripMenuItem});
this.ModeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.CreateProcessModeToolStripMenuItem,
this.CreateRouteTableRuleToolStripMenuItem});
this.ModeToolStripMenuItem.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
this.ModeToolStripMenuItem.Name = "ModeToolStripMenuItem";
this.ModeToolStripMenuItem.Size = new System.Drawing.Size(55, 21);
@@ -163,19 +167,12 @@
this.CreateRouteTableRuleToolStripMenuItem.Text = "Create Route Table Rule";
this.CreateRouteTableRuleToolStripMenuItem.Click += new System.EventHandler(this.createRouteTableModeToolStripMenuItem_Click);
//
// ReloadModesToolStripMenuItem
//
this.ReloadModesToolStripMenuItem.Name = "ReloadModesToolStripMenuItem";
this.ReloadModesToolStripMenuItem.Size = new System.Drawing.Size(217, 22);
this.ReloadModesToolStripMenuItem.Text = "Reload Modes";
this.ReloadModesToolStripMenuItem.Click += new System.EventHandler(this.ReloadModesToolStripMenuItem_Click);
//
// SubscribeToolStripMenuItem
//
this.SubscribeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[]
{
this.ManageSubscribeLinksToolStripMenuItem, this.UpdateServersFromSubscribeLinksToolStripMenuItem, this.UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem
});
this.SubscribeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.ManageSubscribeLinksToolStripMenuItem,
this.UpdateServersFromSubscribeLinksToolStripMenuItem,
this.UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem});
this.SubscribeToolStripMenuItem.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
this.SubscribeToolStripMenuItem.Name = "SubscribeToolStripMenuItem";
this.SubscribeToolStripMenuItem.Size = new System.Drawing.Size(77, 21);
@@ -204,10 +201,15 @@
//
// OptionsToolStripMenuItem
//
this.OptionsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[]
{
this.OpenDirectoryToolStripMenuItem, this.CleanDNSCacheToolStripMenuItem, this.UpdateACLToolStripMenuItem, this.updateACLWithProxyToolStripMenuItem, this.updatePACToolStripMenuItem, this.UninstallServiceToolStripMenuItem, this.UninstallTapDriverToolStripMenuItem, this.removeNetchFirewallRulesToolStripMenuItem
});
this.OptionsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.OpenDirectoryToolStripMenuItem,
this.CleanDNSCacheToolStripMenuItem,
this.UpdateACLToolStripMenuItem,
this.updateACLWithProxyToolStripMenuItem,
this.updatePACToolStripMenuItem,
this.UninstallServiceToolStripMenuItem,
this.UninstallTapDriverToolStripMenuItem,
this.removeNetchFirewallRulesToolStripMenuItem});
this.OptionsToolStripMenuItem.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
this.OptionsToolStripMenuItem.Name = "OptionsToolStripMenuItem";
this.OptionsToolStripMenuItem.Size = new System.Drawing.Size(66, 21);
@@ -271,10 +273,9 @@
//
// HelpToolStripMenuItem
//
this.HelpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[]
{
this.CheckForUpdatesToolStripMenuItem, this.fAQToolStripMenuItem
});
this.HelpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.CheckForUpdatesToolStripMenuItem,
this.fAQToolStripMenuItem});
this.HelpToolStripMenuItem.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
this.HelpToolStripMenuItem.Name = "HelpToolStripMenuItem";
this.HelpToolStripMenuItem.Size = new System.Drawing.Size(47, 21);
@@ -550,10 +551,14 @@
// StatusStrip
//
this.StatusStrip.ImageScalingSize = new System.Drawing.Size(20, 20);
this.StatusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[]
{
this.StatusLabel, this.UsedBandwidthLabel, this.DownloadSpeedLabel, this.UploadSpeedLabel, this.blankToolStripStatusLabel, this.NatTypeStatusLabel, this.NatTypeStatusLightLabel
});
this.StatusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.StatusLabel,
this.UsedBandwidthLabel,
this.DownloadSpeedLabel,
this.UploadSpeedLabel,
this.blankToolStripStatusLabel,
this.NatTypeStatusLabel,
this.NatTypeStatusLightLabel});
this.StatusStrip.Location = new System.Drawing.Point(0, 272);
this.StatusStrip.Name = "StatusStrip";
this.StatusStrip.Size = new System.Drawing.Size(740, 22);
@@ -616,7 +621,7 @@
//
// ControlButton
//
this.ControlButton.Anchor = ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.ControlButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.ControlButton.Location = new System.Drawing.Point(631, 3);
this.ControlButton.Name = "ControlButton";
this.ControlButton.Size = new System.Drawing.Size(75, 27);
@@ -635,10 +640,9 @@
// NotifyMenu
//
this.NotifyMenu.ImageScalingSize = new System.Drawing.Size(20, 20);
this.NotifyMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[]
{
this.ShowMainFormToolStripButton, this.ExitToolStripButton
});
this.NotifyMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.ShowMainFormToolStripButton,
this.ExitToolStripButton});
this.NotifyMenu.Name = "NotifyMenu";
this.NotifyMenu.ShowItemToolTips = false;
this.NotifyMenu.Size = new System.Drawing.Size(108, 48);
@@ -659,7 +663,7 @@
//
// SettingsButton
//
this.SettingsButton.Anchor = ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.SettingsButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.SettingsButton.Location = new System.Drawing.Point(1, 3);
this.SettingsButton.Name = "SettingsButton";
this.SettingsButton.Size = new System.Drawing.Size(72, 27);
@@ -728,7 +732,7 @@
this.Controls.Add(this.MenuStrip);
this.Controls.Add(this.StatusStrip);
this.Controls.Add(this.flowLayoutPanel1);
this.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte) (134)));
this.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
this.MaximizeBox = false;
@@ -744,13 +748,13 @@
this.configLayoutPanel.ResumeLayout(false);
this.configLayoutPanel.PerformLayout();
this.tableLayoutPanel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize) (this.EditServerPictureBox)).EndInit();
((System.ComponentModel.ISupportInitialize) (this.CopyLinkPictureBox)).EndInit();
((System.ComponentModel.ISupportInitialize) (this.DeleteServerPictureBox)).EndInit();
((System.ComponentModel.ISupportInitialize) (this.SpeedPictureBox)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.EditServerPictureBox)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.CopyLinkPictureBox)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.DeleteServerPictureBox)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.SpeedPictureBox)).EndInit();
this.tableLayoutPanel3.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize) (this.EditModePictureBox)).EndInit();
((System.ComponentModel.ISupportInitialize) (this.DeleteModePictureBox)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.EditModePictureBox)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.DeleteModePictureBox)).EndInit();
this.StatusStrip.ResumeLayout(false);
this.StatusStrip.PerformLayout();
this.NotifyMenu.ResumeLayout(false);
@@ -760,6 +764,7 @@
this.ButtomControlContainerControl.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
private System.Windows.Forms.ToolStripMenuItem CreateRouteTableRuleToolStripMenuItem;
@@ -798,7 +803,6 @@
private System.Windows.Forms.TableLayoutPanel ProfileTable;
private System.Windows.Forms.ToolStripMenuItem UninstallTapDriverToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem CheckForUpdatesToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem ReloadModesToolStripMenuItem;
private System.Windows.Forms.ComboBox ServerComboBox;
private System.Windows.Forms.Label ServerLabel;
private System.Windows.Forms.ToolStripMenuItem ServerToolStripMenuItem;

View File

@@ -84,8 +84,6 @@ namespace Netch.Forms
private void MainForm_Load(object sender, EventArgs e)
{
Netch.TimePoint("MainForm ctor (Pre MainForm Load)");
// 计算 ComboBox绘制 目标宽度
RecordSize();
@@ -121,8 +119,6 @@ namespace Netch.Forms
if (Global.Settings.StartWhenOpened)
ControlButton_Click(null, null);
});
Netch.TimePoint("Post Form Load", false);
}
private void RecordSize()
@@ -266,25 +262,6 @@ namespace Netch.Forms
Show();
}
private void ReloadModesToolStripMenuItem_Click(object sender, EventArgs e)
{
Enabled = false;
try
{
ModeHelper.Load();
LoadModes();
NotifyTip(i18N.Translate("Modes have been reload"));
}
catch (Exception)
{
// ignored
}
finally
{
Enabled = true;
}
}
#endregion
#region Subscription
@@ -467,7 +444,7 @@ namespace Netch.Forms
if (useProxy)
req.Proxy = new WebProxy($"http://127.0.0.1:{Global.Settings.HTTPLocalPort}");
await WebUtil.DownloadFileAsync(req, Path.Combine(Global.NetchDir, Global.UserACL));
await WebUtil.DownloadFileAsync(req, Path.Combine(Global.NetchDir, Constants.UserACL));
NotifyTip(i18N.Translate("ACL updated successfully"));
}
catch (Exception e)
@@ -634,9 +611,7 @@ namespace Netch.Forms
if (!IsWaiting())
{
// 停止
State = State.Stopping;
await MainController.StopAsync();
State = State.Stopped;
await StopAsyncCore();
return;
}
@@ -1126,8 +1101,7 @@ namespace Netch.Forms
// 启动需要禁用的控件
UninstallServiceToolStripMenuItem.Enabled = UpdateACLToolStripMenuItem.Enabled = updateACLWithProxyToolStripMenuItem.Enabled =
updatePACToolStripMenuItem.Enabled = UpdateServersFromSubscribeLinksToolStripMenuItem.Enabled =
UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem.Enabled = UninstallTapDriverToolStripMenuItem.Enabled =
ReloadModesToolStripMenuItem.Enabled = enabled;
UpdateServersFromSubscribeLinksWithProxyToolStripMenuItem.Enabled = UninstallTapDriverToolStripMenuItem.Enabled = enabled;
}
_state = value;
@@ -1179,6 +1153,27 @@ namespace Netch.Forms
}
}
private async Task StopAsyncCore()
{
State = State.Stopping;
await MainController.StopAsync();
State = State.Stopped;
}
public void Stop()
{
if (IsWaiting())
return;
if (InvokeRequired)
{
Invoke(new Action(Stop));
return;
}
StopAsyncCore().Wait();
}
private bool IsWaiting()
{
return State == State.Waiting || State == State.Stopped;
@@ -1258,7 +1253,7 @@ namespace Netch.Forms
{
if (natType > 0 && natType < 5)
{
NatTypeStatusLightLabel.Visible = Global.Flags.IsWindows10Upper;
NatTypeStatusLightLabel.Visible = Flags.IsWindows10Upper;
var c = natType switch
{
1 => Color.LimeGreen,
@@ -1388,8 +1383,8 @@ namespace Netch.Forms
if (File.Exists(file))
File.Delete(file);
if (!IsWaiting())
await MainController.StopAsync();
if (IsWaiting())
await StopAsyncCore();
Dispose();
Environment.Exit(Environment.ExitCode);
@@ -1425,6 +1420,8 @@ namespace Netch.Forms
{
UpdateChecker.NewVersionFound += OnUpdateCheckerOnNewVersionFound;
UpdateChecker.Check(Global.Settings.CheckBetaUpdate).Wait();
if (Flags.AlwaysShowNewVersionFound)
OnUpdateCheckerOnNewVersionFound(null!, null!);
}
finally
{
@@ -1482,8 +1479,14 @@ namespace Netch.Forms
#region NotifyIcon
private void ShowMainFormToolStripButton_Click(object sender, EventArgs e)
public void ShowMainFormToolStripButton_Click(object sender, EventArgs e)
{
if (InvokeRequired)
{
Invoke(new Action(() => ShowMainFormToolStripButton_Click(sender, e)));
return;
}
if (WindowState == FormWindowState.Minimized)
{
Visible = true;
@@ -1516,7 +1519,7 @@ namespace Netch.Forms
public void NotifyTip(string text, int timeout = 0, bool info = true)
{
// 会阻塞线程 timeout 秒
// 会阻塞线程 timeout 秒(?)
NotifyIcon.ShowBalloonTip(timeout, UpdateChecker.Name, text, info ? ToolTipIcon.Info : ToolTipIcon.Error);
}

132
Netch/Forms/MainForm.resx Normal file
View File

@@ -0,0 +1,132 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="MenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="StatusStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>130, 17</value>
</metadata>
<metadata name="NotifyIcon.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>246, 17</value>
</metadata>
<metadata name="NotifyMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>359, 17</value>
</metadata>
</root>

View File

@@ -235,7 +235,7 @@ namespace Netch.Forms
private void SettingForm_Load(object sender, EventArgs e)
{
TUNTAPUseCustomDNSCheckBox_CheckedChanged(null, null);
Task.Run(() => BeginInvoke(new Action(() => UseFakeDNSCheckBox.Visible = Global.Flags.SupportFakeDns)));
Task.Run(() => BeginInvoke(new Action(() => UseFakeDNSCheckBox.Visible = Flags.SupportFakeDns)));
}
private void TUNTAPUseCustomDNSCheckBox_CheckedChanged(object? sender, EventArgs? e)

View File

@@ -2,9 +2,7 @@ using System;
using System.Collections.Generic;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading;
using System.Windows.Forms;
using Netch.Controllers;
using Netch.Forms;
using Netch.Models;
@@ -12,27 +10,11 @@ namespace Netch
{
public static class Global
{
/// <summary>
/// 换行
/// </summary>
public const string EOF = "\r\n";
public const string UserACL = "data\\user.acl";
public const string BuiltinACL = "bin\\default.acl";
public static readonly string NetchDir = Application.StartupPath;
public static readonly string NetchExecutable = Application.ExecutablePath;
/// <summary>
/// 主窗体的静态实例
/// </summary>
private static readonly Lazy<MainForm> LazyMainForm = new(() => new MainForm());
private static readonly Lazy<Mutex> LazyMutex = new(() => new Mutex(false, "Global\\Netch"));
public static Mutex Mutex => LazyMutex.Value;
/// <summary>
/// 用于读取和写入的配置
/// </summary>
@@ -43,15 +25,6 @@ namespace Netch
/// </summary>
public static readonly List<Mode> Modes = new();
public static class Flags
{
public static readonly bool IsWindows10Upper = Environment.OSVersion.Version.Major >= 10;
private static readonly Lazy<bool> LazySupportFakeDns = new(() => new TUNTAPController().TestFakeDNS());
public static bool SupportFakeDns => LazySupportFakeDns.Value;
}
/// <summary>
/// 主窗体的静态实例
/// </summary>
@@ -63,5 +36,8 @@ namespace Netch
IgnoreNullValues = true,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
public static readonly string NetchDir = Application.StartupPath;
public static readonly string NetchExecutable = Application.ExecutablePath;
}
}

View File

@@ -161,7 +161,7 @@ namespace Netch.Models
/// <returns>模式文件字符串</returns>
public string ToFileString()
{
return $"# {Remark}, {Type}, {(BypassChina ? 1 : 0)}{Global.EOF}{string.Join(Global.EOF, Rule)}";
return $"# {Remark}, {Type}, {(BypassChina ? 1 : 0)}{Constants.EOF}{string.Join(Constants.EOF, Rule)}";
}
}

View File

@@ -1,42 +1,19 @@
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Netch.Controllers;
using Netch.Forms;
using Netch.Utils;
using Vanara.PInvoke;
using static Vanara.PInvoke.User32;
namespace Netch
{
public static class Netch
{
private static readonly Stopwatch Stopwatch = new();
public static void StartStopwatch(string name)
{
if (Stopwatch.IsRunning)
throw new Exception();
Stopwatch.Start();
Console.WriteLine($"Start {name} Stopwatch");
}
public static void TimePoint(string name, bool restart = true)
{
if (!Stopwatch.IsRunning)
throw new Exception();
Stopwatch.Stop();
Console.WriteLine($"{name} Stopwatch: {Stopwatch.ElapsedMilliseconds}");
if (restart)
Stopwatch.Restart();
}
public static readonly SingleInstance.SingleInstance SingleInstance = new($"Global\\{nameof(Netch)}");
/// <summary>
/// 应用程序的主入口点
@@ -47,10 +24,12 @@ namespace Netch
#if DEBUG
AttachConsole();
#else
if (args.Contains("-console"))
if (args.Contains(Constants.Parameter.Console))
AttachConsole();
#endif
StartStopwatch("Netch");
if (args.Contains(Constants.Parameter.ForceUpdate))
Flags.AlwaysShowNewVersionFound = true;
// 设置当前目录
Directory.SetCurrentDirectory(Global.NetchDir);
@@ -66,20 +45,19 @@ namespace Netch
if (!Directory.Exists(item))
Directory.CreateDirectory(item);
TimePoint("Clean Old, Create Directory");
// 加载配置
Configuration.Load();
TimePoint("Load Configuration");
// 检查是否已经运行
if (!Global.Mutex.WaitOne(0, false))
if (!SingleInstance.IsFirstInstance)
{
ShowOpened();
// 退出进程
Environment.Exit(1);
SingleInstance.PassArgumentsToFirstInstance(args.Append(Constants.Parameter.Show));
Environment.Exit(0);
return;
}
SingleInstance.ArgumentsReceived.Subscribe(SingleInstance_ArgumentsReceived);
SingleInstance.ListenForArgumentsFromSuccessiveInstances();
// 清理上一次的日志文件,防止淤积占用磁盘空间
if (Directory.Exists("logging"))
{
@@ -104,8 +82,6 @@ namespace Netch
Logging.Info($"版本: {UpdateChecker.Owner}/{UpdateChecker.Repo}@{UpdateChecker.Version}");
Task.Run(() => { Logging.Info($"主程序 SHA256: {Utils.Utils.SHA256CheckSum(Global.NetchExecutable)}"); });
TimePoint("Get Info, Pre-Form");
// 绑定错误捕获
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Application.ThreadException += Application_OnException;
@@ -127,40 +103,12 @@ namespace Netch
Utils.Utils.Open(Logging.LogFile);
}
private static void ShowOpened()
private static void SingleInstance_ArgumentsReceived(IEnumerable<string> args)
{
HWND GetWindowHandleByPidAndTitle(int process, string title)
if (args.Contains(Constants.Parameter.Show))
{
var sb = new StringBuilder(256);
HWND pLast = IntPtr.Zero;
do
{
pLast = FindWindowEx(HWND.NULL, pLast, null, null);
GetWindowThreadProcessId(pLast, out var id);
if (id != process)
continue;
if (GetWindowText(pLast, sb, sb.Capacity) <= 0)
continue;
if (sb.ToString().Equals(title))
return pLast;
} while (pLast != IntPtr.Zero);
return HWND.NULL;
Global.MainForm.ShowMainFormToolStripButton_Click(null!, null!);
}
var self = Process.GetCurrentProcess();
var activeProcess = Process.GetProcessesByName("Netch").Single(p => p.Id != self.Id);
HWND handle = activeProcess.MainWindowHandle;
if (handle.IsNull)
handle = GetWindowHandleByPidAndTitle(activeProcess.Id, "Netch");
if (handle.IsNull)
return;
ShowWindow(handle, ShowWindowCommand.SW_NORMAL);
SwitchToThisWindow(handle, true);
}
}
}

View File

@@ -43,6 +43,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="HMBSbige.SingleInstance" Version="5.0.0" />
<PackageReference Include="MaxMind.GeoIP2" Version="4.0.1" />
<PackageReference Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="2.0.66" GeneratePathProperty="true" />
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
@@ -54,9 +55,9 @@
<PackageReference Include="System.Reflection.Metadata" Version="5.0.0" />
<PackageReference Include="System.Text.Json" Version="5.0.1" />
<PackageReference Include="TaskScheduler" Version="2.9.1" />
<PackageReference Include="Vanara.PInvoke.IpHlpApi" Version="3.3.6" />
<PackageReference Include="Vanara.PInvoke.IpHlpApi" Version="3.3.7" />
<PackageReference Include="Microsoft-WindowsAPICodePack-Shell" Version="1.1.4" />
<PackageReference Include="Vanara.PInvoke.User32" Version="3.3.6" />
<PackageReference Include="Vanara.PInvoke.User32" Version="3.3.7" />
<PackageReference Include="WindowsFirewallHelper" Version="2.0.4.70-beta2" />
<PackageReference Include="WindowsProxy" Version="5.0.3" />
</ItemGroup>
@@ -77,6 +78,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Interop.nfapinet\Interop.nfapinet.csproj" />
<ProjectReference Include="..\SearchComboBox\SearchComboBox.csproj" />
</ItemGroup>
@@ -123,7 +125,7 @@
</VisualStudio>
</ProjectExtensions>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="set TargetFramework=$(TargetFramework)&#xD;&#xA;set Configuration=$(Configuration)&#xD;&#xA;set ILMergeConsolePath=$(ILMergeConsolePath)&#xD;&#xA;set TargetDir=$(TargetDir)&#xD;&#xA;set SolutionDir=$(SolutionDir)&#xD;&#xA;$(ProjectDir)PostBuild.bat" />
<Exec Command="set TargetFramework=$(TargetFramework)&#xD;&#xA;set Configuration=$(Configuration)&#xD;&#xA;set ILMergeConsolePath=$(ILMergeConsolePath)&#xD;&#xA;set TargetDir=$(TargetDir)&#xD;&#xA;set SolutionDir=$(SolutionDir)&#xD;&#xA;call $(ProjectDir)PostBuild.bat" />
</Target>
<Target Condition="'$(PublishSingleFile)' == 'true'" AfterTargets="_ComputeFilesToBundle" Name="RemoveDupeAssemblies">

View File

@@ -10,9 +10,9 @@ namespace Netch.Servers.Shadowsocks
{
public override string MainFile { get; protected set; } = "Shadowsocks.exe";
protected override IEnumerable<string> StartedKeywords { get; } = new[] {"listening at"};
protected override IEnumerable<string> StartedKeywords { get; set; } = new[] {"listening at"};
protected override IEnumerable<string> StoppedKeywords { get; } = new[] {"Invalid config path", "usage", "plugin service exit unexpectedly"};
protected override IEnumerable<string> StoppedKeywords { get; set; } = new[] {"Invalid config path", "usage", "plugin service exit unexpectedly"};
public override string Name { get; } = "Shadowsocks";
@@ -38,7 +38,7 @@ namespace Netch.Servers.Shadowsocks
};
if (mode.BypassChina)
command.acl = $"{Path.GetFullPath(File.Exists(Global.UserACL) ? Global.UserACL : Global.BuiltinACL)}";
command.acl = $"{Path.GetFullPath(File.Exists(Constants.UserACL) ? Constants.UserACL : Constants.BuiltinACL)}";
StartInstanceAuto(command.ToString());
}

View File

@@ -10,9 +10,9 @@ namespace Netch.Servers.ShadowsocksR
{
public override string MainFile { get; protected set; } = "ShadowsocksR.exe";
protected override IEnumerable<string> StartedKeywords { get; } = new[] {"listening at"};
protected override IEnumerable<string> StartedKeywords { get; set; } = new[] {"listening at"};
protected override IEnumerable<string> StoppedKeywords { get; } = new[] {"Invalid config path", "usage"};
protected override IEnumerable<string> StoppedKeywords { get; set; } = new[] {"Invalid config path", "usage"};
public override string Name { get; } = "ShadowsocksR";
@@ -41,7 +41,7 @@ namespace Netch.Servers.ShadowsocksR
};
if (mode.BypassChina)
command.acl = $"{Path.GetFullPath(File.Exists(Global.UserACL) ? Global.UserACL : Global.BuiltinACL)}";
command.acl = $"{Path.GetFullPath(File.Exists(Constants.UserACL) ? Constants.UserACL : Constants.BuiltinACL)}";
StartInstanceAuto(command.ToString());
}

View File

@@ -40,7 +40,7 @@ namespace Netch.Servers.ShadowsocksR
// https://github.com/shadowsocksr-backup/shadowsocks-rss/wiki/SSR-QRcode-scheme
// ssr://base64(host:port:protocol:method:obfs:base64pass/?obfsparam=base64param&protoparam=base64param&remarks=base64remarks&group=base64group&udpport=0&uot=0)
var paraStr =
$"/?obfsparam={ShareLink.URLSafeBase64Encode(server.OBFSParam)}&protoparam={ShareLink.URLSafeBase64Encode(server.ProtocolParam)}&remarks={ShareLink.URLSafeBase64Encode(server.Remark)}";
$"/?obfsparam={ShareLink.URLSafeBase64Encode(server.OBFSParam ?? "")}&protoparam={ShareLink.URLSafeBase64Encode(server.ProtocolParam ?? "")}&remarks={ShareLink.URLSafeBase64Encode(server.Remark)}";
return "ssr://" +
ShareLink.URLSafeBase64Encode(

View File

@@ -11,9 +11,9 @@ namespace Netch.Servers.Trojan
{
public override string MainFile { get; protected set; } = "Trojan.exe";
protected override IEnumerable<string> StartedKeywords { get; } = new[] {"started"};
protected override IEnumerable<string> StartedKeywords { get; set; } = new[] {"started"};
protected override IEnumerable<string> StoppedKeywords { get; } = new[] {"exiting"};
protected override IEnumerable<string> StoppedKeywords { get; set; } = new[] {"exiting"};
public override string Name { get; } = "Trojan";

View File

@@ -73,7 +73,7 @@ namespace Netch.Servers.V2ray.Utils
break;
case 1:
case 2:
if (Global.Flags.SupportFakeDns && Global.Settings.TUNTAP.UseFakeDNS)
if (Flags.SupportFakeDns && Global.Settings.TUNTAP.UseFakeDNS)
directRuleObject.domain.Add("geosite:cn");
else
directRuleObject.ip.Add("geoip:cn");

View File

@@ -10,9 +10,9 @@ namespace Netch.Servers.V2ray
{
public override string MainFile { get; protected set; } = "xray.exe";
protected override IEnumerable<string> StartedKeywords { get; } = new[] {"started"};
protected override IEnumerable<string> StartedKeywords { get; set; } = new[] {"started"};
protected override IEnumerable<string> StoppedKeywords { get; } = new[] {"config file not readable", "failed to"};
protected override IEnumerable<string> StoppedKeywords { get; set; } = new[] {"config file not readable", "failed to"};
public override string Name { get; } = "Xray";

View File

@@ -6,6 +6,7 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows.Threading;
using Netch.Controllers;
using Netch.Properties;
using Netch.Utils;
@@ -95,10 +96,19 @@ namespace Netch.Updater
private void ApplyUpdate()
{
// Pre Update
var dispatcher = Dispatcher.CurrentDispatcher;
var mainForm = Global.MainForm;
#region PreUpdate
ModeHelper.SuspendWatcher = true;
// Stop and Save
mainForm.Stop();
Configuration.Save();
// Backup Configuration file
try
{
// Backup Configuration file
File.Copy(Configuration.SettingFileFullName, Configuration.SettingFileFullName + ".bak", true);
}
catch (Exception)
@@ -106,6 +116,8 @@ namespace Netch.Updater
// ignored
}
#endregion
// extract Update file to {tempDirectory}\extract
var extractPath = Path.Combine(_tempDirectory, "extract");
int exitCode;
@@ -118,11 +130,10 @@ namespace Netch.Updater
// move {tempDirectory}\extract\Netch to install folder
MoveAllFilesOver(Path.Combine(extractPath, "Netch"), _installDirectory);
// save, release mutex, then exit
Configuration.Save();
Global.MainForm.Invoke(new Action(() => { Global.Mutex.ReleaseMutex(); }));
// release mutex, exit
dispatcher.Invoke(Netch.SingleInstance.Dispose);
Process.Start(Global.NetchExecutable);
Global.MainForm.Exit(true, false);
Environment.Exit(0);
}
private void MarkFilesOld()

View File

@@ -45,7 +45,7 @@ namespace Netch.Utils
/// </summary>
public static void NetTraffic()
{
if (!Global.Flags.IsWindows10Upper)
if (!Flags.IsWindows10Upper)
return;
var counterLock = new object();

View File

@@ -39,7 +39,7 @@ namespace Netch.Utils
private static void Write(string text, LogLevel logLevel)
{
var contents = $@"[{DateTime.Now}][{logLevel.ToString()}] {text}{Global.EOF}";
var contents = $@"[{DateTime.Now}][{logLevel.ToString()}] {text}{Constants.EOF}";
#if DEBUG
switch (logLevel)
{

View File

@@ -16,6 +16,8 @@ namespace Netch.Utils
private static readonly FileSystemWatcher FileSystemWatcher;
public static bool SuspendWatcher { get; set; } = false;
static ModeHelper()
{
FileSystemWatcher = new FileSystemWatcher(ModeDirectoryFullName)
@@ -33,6 +35,9 @@ namespace Netch.Utils
private static void OnModeChanged(object sender, FileSystemEventArgs e)
{
if (SuspendWatcher)
return;
Load();
Global.MainForm.LoadModes();
}

View File

@@ -33,7 +33,7 @@ namespace Netch.Utils
if (port == 0)
throw new ArgumentOutOfRangeException();
var row = GetTcpTable2().Where(r => ntohs((ushort) r.dwLocalPort) == port);
var row = GetTcpTable2().Where(r => ntohs((ushort) r.dwLocalPort) == port).Where(r => r.dwOwningPid is not (0 or 4));
return row.Select(r => Process.GetProcessById((int) r.dwOwningPid));
}