From d5e1ef1a56e8d69cb2a6a8c0bc7a49d613df8606 Mon Sep 17 00:00:00 2001 From: ChsBuffer <33744752+chsbuffer@users.noreply.github.com> Date: Mon, 5 Jul 2021 06:02:07 +0800 Subject: [PATCH] Migrate to CsWin32 --- Netch/Forms/LogForm.cs | 17 ++++++------- Netch/Forms/MainForm.cs | 11 +++++---- Netch/Models/NetRoute.cs | 6 ++--- Netch/NativeMethods.txt | 21 ++++++++++++++++ Netch/Netch.cs | 12 ++++++---- Netch/Netch.csproj | 6 +++-- Netch/Utils/NetworkInterfaceUtils.cs | 5 ++-- Netch/Utils/PortHelper.cs | 36 ++++++++++++++++++++++++---- 8 files changed, 84 insertions(+), 30 deletions(-) create mode 100644 Netch/NativeMethods.txt diff --git a/Netch/Forms/LogForm.cs b/Netch/Forms/LogForm.cs index cf68e5e3..7726c82e 100644 --- a/Netch/Forms/LogForm.cs +++ b/Netch/Forms/LogForm.cs @@ -1,8 +1,9 @@ using System; using System.ComponentModel; using System.Windows.Forms; -using Vanara.PInvoke; -using static Vanara.PInvoke.User32; +using Windows.Win32.Foundation; +using Windows.Win32.UI.WindowsAndMessaging; +using static Windows.Win32.PInvoke; namespace Netch.Forms { @@ -34,21 +35,21 @@ namespace Netch.Forms private void Parent_Activated(object? sender, EventArgs? e) { - SetWindowPos(Handle, - HWND.HWND_TOPMOST, + SetWindowPos(new HWND(Handle), + new HWND(-1), 0, 0, 0, 0, - SetWindowPosFlags.SWP_NOACTIVATE | SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOSIZE | SetWindowPosFlags.SWP_SHOWWINDOW); + SET_WINDOW_POS_FLAGS.SWP_NOACTIVATE | SET_WINDOW_POS_FLAGS.SWP_NOMOVE | SET_WINDOW_POS_FLAGS.SWP_NOSIZE | SET_WINDOW_POS_FLAGS.SWP_SHOWWINDOW); - SetWindowPos(Handle, - HWND.HWND_NOTOPMOST, + SetWindowPos(new HWND(Handle), + new HWND(-2), 0, 0, 0, 0, - SetWindowPosFlags.SWP_NOACTIVATE | SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOSIZE | SetWindowPosFlags.SWP_SHOWWINDOW); + SET_WINDOW_POS_FLAGS.SWP_NOACTIVATE | SET_WINDOW_POS_FLAGS.SWP_NOMOVE | SET_WINDOW_POS_FLAGS.SWP_NOSIZE | SET_WINDOW_POS_FLAGS.SWP_SHOWWINDOW); } private void richTextBox1_TextChanged(object? sender, EventArgs? e) diff --git a/Netch/Forms/MainForm.cs b/Netch/Forms/MainForm.cs index 4a9a85a3..cef69a8a 100644 --- a/Netch/Forms/MainForm.cs +++ b/Netch/Forms/MainForm.cs @@ -9,6 +9,9 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; +using Windows.Win32; +using Windows.Win32.Foundation; +using Windows.Win32.UI.WindowsAndMessaging; using Microsoft.Win32; using Netch.Controllers; using Netch.Enums; @@ -19,7 +22,6 @@ using Netch.Properties; using Netch.Services; using Netch.Utils; using Serilog; -using Vanara.PInvoke; namespace Netch.Forms { @@ -391,9 +393,10 @@ namespace Netch.Forms private void ShowHideConsoleToolStripMenuItem_Click(object sender, EventArgs e) { - var windowStyles = (User32.WindowStyles)User32.GetWindowLong(Netch.ConsoleHwnd, User32.WindowLongFlags.GWL_STYLE); - var visible = windowStyles.HasFlag(User32.WindowStyles.WS_VISIBLE); - User32.ShowWindow(Netch.ConsoleHwnd, visible ? ShowWindowCommand.SW_HIDE : ShowWindowCommand.SW_SHOWNOACTIVATE); + + var windowStyles = (WINDOW_STYLE)PInvoke.GetWindowLong(new HWND(Netch.ConsoleHwnd), WINDOW_LONG_PTR_INDEX.GWL_STYLE); + var visible = windowStyles.HasFlag(WINDOW_STYLE.WS_VISIBLE); + PInvoke.ShowWindow(Netch.ConsoleHwnd, visible ? SHOW_WINDOW_CMD.SW_HIDE : SHOW_WINDOW_CMD.SW_SHOWNOACTIVATE); } #endregion diff --git a/Netch/Models/NetRoute.cs b/Netch/Models/NetRoute.cs index ee945187..5ff81d73 100644 --- a/Netch/Models/NetRoute.cs +++ b/Netch/Models/NetRoute.cs @@ -1,6 +1,6 @@ using System; using System.Net; -using Vanara.PInvoke; +using Windows.Win32; namespace Netch.Models { @@ -18,10 +18,10 @@ namespace Netch.Models public static NetRoute GetBestRouteTemplate() { - if (IpHlpApi.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse("114.114.114.114").GetAddressBytes(), 0), 0, out var route) != 0) + if (PInvoke.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse("114.114.114.114").GetAddressBytes(), 0), 0, out var route) != 0) throw new MessageException("GetBestRoute 搜索失败"); - var gateway = new IPAddress(route.dwForwardNextHop.S_un_b); + var gateway = new IPAddress(route.dwForwardNextHop); return TemplateBuilder(gateway.ToString(), (int)route.dwForwardIfIndex); } diff --git a/Netch/NativeMethods.txt b/Netch/NativeMethods.txt new file mode 100644 index 00000000..1b515f2a --- /dev/null +++ b/Netch/NativeMethods.txt @@ -0,0 +1,21 @@ +// IpHlpApi.dll +GetBestRoute +GetExtendedTcpTable +MIB_TCPTABLE_OWNER_PID +ADDRESS_FAMILY + +// User32.dll +SetWindowPos +GetWindowLong +ShowWindow +WINDOW_STYLE + +// Kernel32.dll +AllocConsole +GetConsoleWindow + +// Ws2_32.dll +ntohs + +// Windows.h +// WIN32_ERROR \ No newline at end of file diff --git a/Netch/Netch.cs b/Netch/Netch.cs index a457ce4b..e11bae53 100644 --- a/Netch/Netch.cs +++ b/Netch/Netch.cs @@ -5,13 +5,15 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; +using Windows.Win32; +using Windows.Win32.Foundation; +using Windows.Win32.UI.WindowsAndMessaging; using Netch.Controllers; using Netch.Forms; using Netch.Services; using Netch.Utils; using Serilog; using Serilog.Events; -using Vanara.PInvoke; namespace Netch { @@ -19,7 +21,7 @@ namespace Netch { public static readonly SingleInstance.SingleInstanceService SingleInstance = new($"Global\\{nameof(Netch)}"); - public static HWND ConsoleHwnd { get; private set; } + internal static HWND ConsoleHwnd { get; private set; } /// /// 应用程序的主入口点 @@ -103,11 +105,11 @@ namespace Netch private static void InitConsole() { - Kernel32.AllocConsole(); + PInvoke.AllocConsole(); - ConsoleHwnd = Kernel32.GetConsoleWindow(); + ConsoleHwnd = PInvoke.GetConsoleWindow(); #if RELEASE - User32.ShowWindow(ConsoleHwnd, ShowWindowCommand.SW_HIDE); + PInvoke.ShowWindow(ConsoleHwnd, SHOW_WINDOW_CMD.SW_HIDE); #endif } diff --git a/Netch/Netch.csproj b/Netch/Netch.csproj index c6797ec5..c013981d 100644 --- a/Netch/Netch.csproj +++ b/Netch/Netch.csproj @@ -39,6 +39,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -52,9 +56,7 @@ - - diff --git a/Netch/Utils/NetworkInterfaceUtils.cs b/Netch/Utils/NetworkInterfaceUtils.cs index 6857b538..ee12b60a 100644 --- a/Netch/Utils/NetworkInterfaceUtils.cs +++ b/Netch/Utils/NetworkInterfaceUtils.cs @@ -5,9 +5,8 @@ using System.Management; using System.Net; using System.Net.NetworkInformation; using System.Net.Sockets; -using System.Threading.Tasks; using Netch.Models; -using Vanara.PInvoke; +using Windows.Win32; namespace Netch.Utils { @@ -22,7 +21,7 @@ namespace Netch.Utils _ => throw new ArgumentOutOfRangeException(nameof(addressFamily), addressFamily, null) }; - if (IpHlpApi.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse(ipAddress).GetAddressBytes(), 0), 0, out var route) != 0) + if (PInvoke.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse(ipAddress).GetAddressBytes(), 0), 0, out var route) != 0) throw new MessageException("GetBestRoute 搜索失败"); return Get((int)route.dwForwardIfIndex); diff --git a/Netch/Utils/PortHelper.cs b/Netch/Utils/PortHelper.cs index 2c5b0c98..13dd0749 100644 --- a/Netch/Utils/PortHelper.cs +++ b/Netch/Utils/PortHelper.cs @@ -1,12 +1,14 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Net.NetworkInformation; +using System.Runtime.InteropServices; +using Windows.Win32; +using Windows.Win32.NetworkManagement.IpHelper; using Netch.Models; using Serilog; -using static Vanara.PInvoke.IpHlpApi; -using static Vanara.PInvoke.Ws2_32; namespace Netch.Utils { @@ -29,14 +31,38 @@ namespace Netch.Utils } } - public static IEnumerable GetProcessByUsedTcpPort(ushort port) + internal static IEnumerable GetProcessByUsedTcpPort(ushort port, ADDRESS_FAMILY inet = ADDRESS_FAMILY.AF_INET) { if (port == 0) throw new ArgumentOutOfRangeException(); - var row = GetTcpTable2().Where(r => ntohs((ushort)r.dwLocalPort) == port).Where(r => r.dwOwningPid is not (0 or 4)); + if (inet is ADDRESS_FAMILY.AF_UNSPEC) + throw new ArgumentOutOfRangeException(nameof(inet)); - return row.Select(r => Process.GetProcessById((int)r.dwOwningPid)); + var process = new List(); + unsafe + { + uint err; + uint size = 0; + PInvoke.GetExtendedTcpTable(default, ref size, false, (uint)inet, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_LISTENER, 0); // get size + var tcpTable = (MIB_TCPTABLE_OWNER_PID*)Marshal.AllocHGlobal((int)size); + + if ((err = PInvoke.GetExtendedTcpTable(tcpTable, ref size, false, (uint)inet, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_LISTENER, 0)) != 0) + throw new Win32Exception((int)err); + + for (var i = 0; i < tcpTable->dwNumEntries; i++) + { + var row = tcpTable->table.ReadOnlyItemRef(i); + + if (row.dwOwningPid is 0 or 4) + continue; + + if (PInvoke.ntohs((ushort)row.dwLocalPort) == port) + process.Add(Process.GetProcessById((int)row.dwOwningPid)); + } + } + + return process; } private static void GetReservedPortRange(PortType portType, ref List targetList)