Refactor Start Port Check Kill Process

This commit is contained in:
ChsBuffer
2021-03-21 03:27:32 +08:00
parent c69c40750a
commit d08a9d5bfd
4 changed files with 41 additions and 30 deletions

View File

@@ -1,11 +1,11 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Netch.Models;
using Netch.Servers.Socks5;
using Netch.Utils;
using static Netch.Utils.PortHelper;
namespace Netch.Controllers
{
@@ -105,10 +105,7 @@ namespace Netch.Controllers
{
controller = ServerHelper.GetUtilByTypeName(server.Type).GetController();
if (controller is Guard instanceController)
Utils.Utils.KillProcessByName(instanceController.MainFile);
PortCheck(controller.Socks5LocalPort(), "Socks5");
TryReleaseTcpPort(controller.Socks5LocalPort(), "Socks5");
Global.MainForm.StatusText(i18N.TranslateFormat("Starting {0}", controller.Name));
@@ -133,13 +130,13 @@ namespace Netch.Controllers
private static void StartMode(Mode mode)
{
ModeController = ModeHelper.GetModeControllerByType(mode.Type, out var port, out var portName, out var portType);
ModeController = ModeHelper.GetModeControllerByType(mode.Type, out var port, out var portName);
if (ModeController == null)
return;
if (port != null)
PortCheck((ushort) port, portName, portType);
TryReleaseTcpPort((ushort) port, portName);
Global.MainForm.StatusText(i18N.TranslateFormat("Starting {0}", ModeController.Name));
@@ -189,7 +186,7 @@ namespace Netch.Controllers
{
try
{
CheckPort(port, portType);
PortHelper.CheckPort(port, portType);
}
catch (PortInUseException)
{
@@ -200,6 +197,27 @@ namespace Netch.Controllers
throw new MessageException(i18N.TranslateFormat("The {0} port is reserved by system.", $"{portName} ({port})"));
}
}
public static void TryReleaseTcpPort(ushort port, string portName)
{
Process? p;
if ((p = PortHelper.GetProcessByUsedTcpPort(port)) != null)
{
if (p.MainModule!.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}"));
}
}
PortCheck(port, portName, PortType.TCP);
}
}
public class MessageException : Exception

View File

@@ -137,17 +137,15 @@ namespace Netch.Utils
};
}
public static IModeController? GetModeControllerByType(int type, out ushort? port, out string portName, out PortType portType)
public static IModeController? GetModeControllerByType(int type, out ushort? port, out string portName)
{
port = null;
portName = string.Empty;
portType = PortType.Both;
switch (type)
{
case 0:
port = Global.Settings.RedirectorTCPPort;
portName = "Redirector TCP";
portType = PortType.TCP;
return new NFController();
case 1:
case 2:
@@ -156,7 +154,6 @@ namespace Netch.Utils
case 5:
port = Global.Settings.HTTPLocalPort;
portName = "HTTP";
portType = PortType.TCP;
StatusPortInfoText.HttpPort = (ushort) port;
return new HTTPController();
case 4:

View File

@@ -4,6 +4,8 @@ using System.Diagnostics;
using System.Linq;
using System.Net.NetworkInformation;
using Netch.Models;
using static Vanara.PInvoke.IpHlpApi;
using static Vanara.PInvoke.Ws2_32;
namespace Netch.Utils
{
@@ -26,6 +28,18 @@ namespace Netch.Utils
}
}
public static Process? GetProcessByUsedTcpPort(ushort port)
{
if (port == 0)
throw new ArgumentOutOfRangeException();
var row = GetTcpTable2().SingleOrDefault(r => ntohs((ushort) r.dwLocalPort) == port);
if (row.dwOwningPid == 0)
return null;
return Process.GetProcessById((int) row.dwOwningPid);
}
private static void GetReservedPortRange(PortType portType, ref List<Range> targetList)
{
var process = new Process

View File

@@ -114,24 +114,6 @@ namespace Netch.Utils
}
}
public static void KillProcessByName(string name)
{
try
{
foreach (var p in Process.GetProcessesByName(name))
if (p.MainModule != null && p.MainModule.FileName.StartsWith(Global.NetchDir))
p.Kill();
}
catch (Win32Exception e)
{
Logging.Error($"结束进程 {name} 错误:" + e.Message);
}
catch (Exception)
{
// ignored
}
}
public static string GetFileVersion(string file)
{
return File.Exists(file) ? FileVersionInfo.GetVersionInfo(file).FileVersion : string.Empty;