PortProxyGUI.1.4.0

This commit is contained in:
zmjack 2023-03-10 03:32:22 +08:00
parent ff14a3532a
commit f3bb505cfe
27 changed files with 867 additions and 478 deletions

View File

@ -1,4 +1,5 @@
using System;
using PortProxyGUI.Utils;
using System;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
@ -14,7 +15,7 @@ namespace PortProxyGUI
PortProxyGUI = portProxyGUI;
InitializeComponent();
Font = Util.UiFont;
Font = InterfaceUtil.UiFont;
label_version.Text = label_version.Text + " v" + Application.ProductVersion;
}

View File

@ -0,0 +1,53 @@
using System;
using System.Drawing;
using System.Linq;
using System.Text.RegularExpressions;
namespace PortProxyGUI.Data
{
public class AppConfig
{
public Size MainWindowSize = new(720, 500);
public int[] PortProxyColumnWidths = new int[] { 24, 64, 140, 100, 140, 100, 100 };
private readonly Regex _intArrayRegex = new(@"^\[\s*(\d+)(?:\s*,\s*(\d+))*\s*\]$");
public AppConfig() { }
public AppConfig(Config[] rows)
{
{
var item = rows.Where(x => x.Item == "MainWindow");
if (int.TryParse(item.FirstOrDefault(x => x.Key == "Width")?.Value, out var width)
&& int.TryParse(item.FirstOrDefault(x => x.Key == "Height")?.Value, out var height))
{
MainWindowSize = new Size(width, height);
}
else MainWindowSize = new Size(720, 500);
}
{
var item = rows.Where(x => x.Item == "PortProxy");
var s_ColumnWidths = item.FirstOrDefault(x => x.Key == "ColumnWidths").Value;
var match = _intArrayRegex.Match(s_ColumnWidths);
if (match.Success)
{
PortProxyColumnWidths = match.Groups
.OfType<Group>().Skip(1)
.SelectMany(x => x.Captures.OfType<Capture>())
.Select(x => int.Parse(x.Value))
.ToArray();
}
else
{
#if NETCOREAPP3_0_OR_GREATER
PortProxyColumnWidths = Array.Empty<int>();
#else
PortProxyColumnWidths = new int[0];
#endif
}
}
}
}
}

View File

@ -1,4 +1,5 @@
using SQLib.Sqlite;
using NStandard;
using SQLib.Sqlite;
using System;
using System.Collections.Generic;
using System.IO;
@ -8,11 +9,27 @@ namespace PortProxyGUI.Data
{
public class ApplicationDbScope : SqliteScope<ApplicationDbScope>
{
public static readonly string DbDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "PortProxyGUI");
public static readonly string DbFile = Path.Combine(DbDirectory, "config.db");
private static readonly string ConnectionString = $"Data Source={DbFile}";
public static readonly string AppDbDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "PortProxyGUI");
public static readonly string AppDbFile = Path.Combine(AppDbDirectory, "config.db");
public static ApplicationDbScope UseDefault() => new ApplicationDbScope(ConnectionString);
public static ApplicationDbScope FromFile(string file)
{
var dir = Path.GetDirectoryName(file);
var fileName = Path.GetFileName(file);
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
if (!File.Exists(fileName))
{
#if NETCOREAPP3_0_OR_GREATER
#else
System.Data.SQLite.SQLiteConnection.CreateFile(file);
#endif
}
var scope = new ApplicationDbScope($"Data Source=\"{file}\"");
scope.Migrate();
return scope;
}
public ApplicationDbScope(string connectionString) : base(connectionString)
{
@ -20,16 +37,14 @@ namespace PortProxyGUI.Data
public override void Initialize()
{
if (!Directory.Exists(DbDirectory)) Directory.CreateDirectory(DbDirectory);
if (!File.Exists(DbFile))
{
#if NET35 || NET45
System.Data.SQLite.SQLiteConnection.CreateFile(DbFile);
#endif
}
}
public void Migrate() => new ApplicationDbMigrationUtil(this).MigrateToLast();
public void Migrate() => new MigrationUtil(this).MigrateToLast();
public Migration GetLastMigration()
{
return SqlQuery<Migration>($"SELECT * FROM __history ORDER BY MigrationId DESC LIMIT 1;").First();
}
public IEnumerable<Rule> Rules => SqlQuery<Rule>($"SELECT * FROM Rules;");
@ -79,5 +94,21 @@ namespace PortProxyGUI.Data
foreach (var obj in objs) Remove(obj);
}
public AppConfig GetAppConfig()
{
var configRows = SqlQuery<Config>($"SELECT * FROM Configs;");
var appConfig = new AppConfig(configRows);
return appConfig;
}
public void SaveAppConfig(AppConfig appConfig)
{
Sql($"UPDATE Configs SET Value = {appConfig.MainWindowSize.Width} WHERE Item = 'MainWindow' AND `Key` = 'Width';");
Sql($"UPDATE Configs SET Value = {appConfig.MainWindowSize.Height} WHERE Item = 'MainWindow' AND `Key` = 'Height';");
var s_portProxyColumnWidths = $"[{appConfig.PortProxyColumnWidths.Select(x => x.ToString()).Join(", ")}]";
Sql($"UPDATE Configs SET Value = {s_portProxyColumnWidths} WHERE Item = 'PortProxy' AND `Key` = 'ColumnWidths';");
}
}
}

View File

@ -0,0 +1,9 @@
namespace PortProxyGUI.Data
{
public class Config
{
public string Item { get; set; }
public string Key { get; set; }
public string Value { get; set; }
}
}

View File

@ -7,11 +7,11 @@ using System.Windows.Forms;
namespace PortProxyGUI.Data
{
public class ApplicationDbMigrationUtil
public class MigrationUtil
{
public ApplicationDbScope DbScope { get; private set; }
public ApplicationDbMigrationUtil(ApplicationDbScope context)
public MigrationUtil(ApplicationDbScope context)
{
DbScope = context;
EnsureHistoryTable();
@ -29,7 +29,7 @@ namespace PortProxyGUI.Data
public void EnsureUpdateVersion()
{
var migration = GetLastMigration();
var migration = DbScope.GetLastMigration();
var assemblyVersion = Assembly.GetExecutingAssembly().GetName().Version;
if (new Version(migration.ProductVersion) > assemblyVersion)
@ -47,14 +47,9 @@ Would you like to download it now?", "Upgrade", MessageBoxButtons.YesNo, Message
}
}
public Migration GetLastMigration()
{
return DbScope.SqlQuery<Migration>($"SELECT * FROM __history ORDER BY MigrationId DESC LIMIT 1;").First();
}
public void MigrateToLast()
{
var migration = GetLastMigration();
var migration = DbScope.GetLastMigration();
var migrationId = migration.MigrationId;
var pendingMigrations = migrationId != "000000000000"
? History.SkipWhile(pair => pair.Key.MigrationId != migrationId).Skip(1)
@ -112,6 +107,21 @@ Would you like to download it now?", "Upgrade", MessageBoxButtons.YesNo, Message
"INSERT INTO rules SELECT Id, Type, ListenOn, ListenPort, ConnectTo, ConnectPort, Note, `Group` FROM rulesOld;",
"DROP TABLE rulesOld;",
},
[new MigrationKey { MigrationId = "202303092024", ProductVersion = "1.4.0" }] = new[]
{
@"CREATE TABLE configs (
Item text,
`Key` text,
Value text
);",
"CREATE UNIQUE INDEX IX_Configs_Key ON configs ( Item, `Key` );",
"INSERT INTO configs ( Item, `Key`, Value ) VALUES ( 'MainWindow', 'Width', '720' );",
"INSERT INTO configs ( Item, `Key`, Value ) VALUES ( 'MainWindow', 'Height', '500' );",
"INSERT INTO configs ( Item, `Key`, Value ) VALUES ( 'PortProxy', 'ColumnWidths', '[24, 64, 140, 100, 140, 100, 100]' );",
},
};
}
}

View File

@ -60,5 +60,10 @@ namespace PortProxyGUI.Data
if (int.TryParse(portString, out var port) && 0 < port && port < 65536) return port;
else throw new NotSupportedException($"Invalid port string. ({portString})");
}
public override bool Equals(object obj)
{
return Equals(obj as Rule);
}
}
}

View File

@ -0,0 +1,10 @@
using System;
namespace PortProxyGUI.Native
{
[Flags]
public enum GenericRights : uint
{
GENERIC_READ = 0x80000000,
}
}

View File

@ -0,0 +1,22 @@
using System;
using System.Runtime.InteropServices;
namespace PortProxyGUI.Native
{
internal class NativeMethods
{
[DllImport("advapi32.dll", EntryPoint = "OpenSCManagerW", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
public static extern IntPtr OpenSCManager(string machineName, string databaseName, uint dwAccess);
[DllImport("advapi32.dll", EntryPoint = "OpenServiceW", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr OpenService(IntPtr hSCManager, string lpServiceName, ServiceRights dwDesiredAccess);
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ControlService(IntPtr hService, ServiceControls dwControl, ref ServiceStatus lpServiceStatus);
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseServiceHandle(IntPtr hSCObject);
}
}

View File

@ -0,0 +1,10 @@
using System;
namespace PortProxyGUI.Native
{
[Flags]
public enum ServiceControls : uint
{
SERVICE_CONTROL_PARAMCHANGE = 0x00000006,
}
}

View File

@ -0,0 +1,10 @@
using System;
namespace PortProxyGUI.Native
{
[Flags]
public enum ServiceRights : uint
{
SERVICE_PAUSE_CONTINUE = 0x0040,
}
}

View File

@ -0,0 +1,16 @@
using System.Runtime.InteropServices;
namespace PortProxyGUI.Native
{
[StructLayout(LayoutKind.Sequential)]
public struct ServiceStatus
{
public uint dwServiceType;
public uint dwCurrentState;
public uint dwControlsAccepted;
public uint dwWin32ExitCode;
public uint dwServiceSpecificExitCode;
public uint dwCheckPoint;
public uint dwWaitHint;
}
}

View File

@ -28,184 +28,219 @@
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PortProxyGUI));
this.listViewProxies = new System.Windows.Forms.ListView();
this.columnHeader1 = new System.Windows.Forms.ColumnHeader();
this.columnHeader2 = new System.Windows.Forms.ColumnHeader();
this.columnHeader3 = new System.Windows.Forms.ColumnHeader();
this.columnHeader4 = new System.Windows.Forms.ColumnHeader();
this.columnHeader5 = new System.Windows.Forms.ColumnHeader();
this.columnHeader6 = new System.Windows.Forms.ColumnHeader();
this.columnHeader7 = new System.Windows.Forms.ColumnHeader();
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
this.toolStripMenuItem_Enable = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem_Disable = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
this.toolStripMenuItem_Refresh = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem_FlushDnsCache = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.toolStripMenuItem_New = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem_Modify = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem_Delete = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.toolStripMenuItem_About = new System.Windows.Forms.ToolStripMenuItem();
this.imageListProxies = new System.Windows.Forms.ImageList(this.components);
this.contextMenuStrip1.SuspendLayout();
this.SuspendLayout();
listViewProxies = new System.Windows.Forms.ListView();
columnHeader1 = new System.Windows.Forms.ColumnHeader();
columnHeader2 = new System.Windows.Forms.ColumnHeader();
columnHeader3 = new System.Windows.Forms.ColumnHeader();
columnHeader4 = new System.Windows.Forms.ColumnHeader();
columnHeader5 = new System.Windows.Forms.ColumnHeader();
columnHeader6 = new System.Windows.Forms.ColumnHeader();
columnHeader7 = new System.Windows.Forms.ColumnHeader();
contextMenuStrip_RightClick = new System.Windows.Forms.ContextMenuStrip(components);
toolStripMenuItem_Enable = new System.Windows.Forms.ToolStripMenuItem();
toolStripMenuItem_Disable = new System.Windows.Forms.ToolStripMenuItem();
toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
toolStripMenuItem_Refresh = new System.Windows.Forms.ToolStripMenuItem();
toolStripMenuItem_FlushDnsCache = new System.Windows.Forms.ToolStripMenuItem();
toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
toolStripMenuItem_New = new System.Windows.Forms.ToolStripMenuItem();
toolStripMenuItem_Modify = new System.Windows.Forms.ToolStripMenuItem();
toolStripMenuItem_Delete = new System.Windows.Forms.ToolStripMenuItem();
toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
toolStripMenuItem_More = new System.Windows.Forms.ToolStripMenuItem();
toolStripMenuItem_Import = new System.Windows.Forms.ToolStripMenuItem();
toolStripMenuItem_Export = new System.Windows.Forms.ToolStripMenuItem();
toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator();
toolStripMenuItem_About = new System.Windows.Forms.ToolStripMenuItem();
imageListProxies = new System.Windows.Forms.ImageList(components);
saveFileDialog_Export = new System.Windows.Forms.SaveFileDialog();
openFileDialog_Import = new System.Windows.Forms.OpenFileDialog();
toolStripMenuItem_ResetWindowSize = new System.Windows.Forms.ToolStripMenuItem();
toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator();
contextMenuStrip_RightClick.SuspendLayout();
SuspendLayout();
//
// listViewProxies
//
this.listViewProxies.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.listViewProxies.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeader1,
this.columnHeader2,
this.columnHeader3,
this.columnHeader4,
this.columnHeader5,
this.columnHeader6,
this.columnHeader7});
this.listViewProxies.ContextMenuStrip = this.contextMenuStrip1;
resources.ApplyResources(this.listViewProxies, "listViewProxies");
this.listViewProxies.FullRowSelect = true;
this.listViewProxies.HideSelection = false;
this.listViewProxies.Name = "listViewProxies";
this.listViewProxies.SmallImageList = this.imageListProxies;
this.listViewProxies.UseCompatibleStateImageBehavior = false;
this.listViewProxies.View = System.Windows.Forms.View.Details;
this.listViewProxies.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.listView1_ColumnClick);
this.listViewProxies.DoubleClick += new System.EventHandler(this.listView1_DoubleClick);
this.listViewProxies.KeyUp += new System.Windows.Forms.KeyEventHandler(this.listViewProxies_KeyUp);
this.listViewProxies.MouseUp += new System.Windows.Forms.MouseEventHandler(this.listView1_MouseUp);
listViewProxies.BorderStyle = System.Windows.Forms.BorderStyle.None;
listViewProxies.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { columnHeader1, columnHeader2, columnHeader3, columnHeader4, columnHeader5, columnHeader6, columnHeader7 });
listViewProxies.ContextMenuStrip = contextMenuStrip_RightClick;
resources.ApplyResources(listViewProxies, "listViewProxies");
listViewProxies.FullRowSelect = true;
listViewProxies.HideSelection = false;
listViewProxies.Name = "listViewProxies";
listViewProxies.SmallImageList = imageListProxies;
listViewProxies.UseCompatibleStateImageBehavior = false;
listViewProxies.View = System.Windows.Forms.View.Details;
listViewProxies.ColumnClick += listView1_ColumnClick;
listViewProxies.ColumnWidthChanged += listViewProxies_ColumnWidthChanged;
listViewProxies.DoubleClick += listView1_DoubleClick;
listViewProxies.KeyUp += listViewProxies_KeyUp;
listViewProxies.MouseUp += listView1_MouseUp;
//
// columnHeader1
//
resources.ApplyResources(this.columnHeader1, "columnHeader1");
resources.ApplyResources(columnHeader1, "columnHeader1");
//
// columnHeader2
//
resources.ApplyResources(this.columnHeader2, "columnHeader2");
resources.ApplyResources(columnHeader2, "columnHeader2");
//
// columnHeader3
//
resources.ApplyResources(this.columnHeader3, "columnHeader3");
resources.ApplyResources(columnHeader3, "columnHeader3");
//
// columnHeader4
//
this.columnHeader4.Tag = "";
resources.ApplyResources(this.columnHeader4, "columnHeader4");
columnHeader4.Tag = "";
resources.ApplyResources(columnHeader4, "columnHeader4");
//
// columnHeader5
//
resources.ApplyResources(this.columnHeader5, "columnHeader5");
resources.ApplyResources(columnHeader5, "columnHeader5");
//
// columnHeader6
//
this.columnHeader6.Tag = "";
resources.ApplyResources(this.columnHeader6, "columnHeader6");
columnHeader6.Tag = "";
resources.ApplyResources(columnHeader6, "columnHeader6");
//
// columnHeader7
//
resources.ApplyResources(this.columnHeader7, "columnHeader7");
resources.ApplyResources(columnHeader7, "columnHeader7");
//
// contextMenuStrip1
// contextMenuStrip_RightClick
//
this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripMenuItem_Enable,
this.toolStripMenuItem_Disable,
this.toolStripSeparator3,
this.toolStripMenuItem_Refresh,
this.toolStripMenuItem_FlushDnsCache,
this.toolStripSeparator2,
this.toolStripMenuItem_New,
this.toolStripMenuItem_Modify,
this.toolStripMenuItem_Delete,
this.toolStripSeparator1,
this.toolStripMenuItem_About});
this.contextMenuStrip1.Name = "contextMenuStrip1";
resources.ApplyResources(this.contextMenuStrip1, "contextMenuStrip1");
this.contextMenuStrip1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.contextMenuStrip1_MouseClick);
contextMenuStrip_RightClick.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { toolStripMenuItem_Enable, toolStripMenuItem_Disable, toolStripSeparator3, toolStripMenuItem_Refresh, toolStripMenuItem_FlushDnsCache, toolStripSeparator2, toolStripMenuItem_New, toolStripMenuItem_Modify, toolStripMenuItem_Delete, toolStripSeparator1, toolStripMenuItem_More, toolStripSeparator4, toolStripMenuItem_About });
contextMenuStrip_RightClick.Name = "contextMenuStrip1";
resources.ApplyResources(contextMenuStrip_RightClick, "contextMenuStrip_RightClick");
contextMenuStrip_RightClick.MouseClick += contextMenuStrip_RightClick_MouseClick;
//
// toolStripMenuItem_Enable
//
this.toolStripMenuItem_Enable.Name = "toolStripMenuItem_Enable";
resources.ApplyResources(this.toolStripMenuItem_Enable, "toolStripMenuItem_Enable");
toolStripMenuItem_Enable.Name = "toolStripMenuItem_Enable";
resources.ApplyResources(toolStripMenuItem_Enable, "toolStripMenuItem_Enable");
//
// toolStripMenuItem_Disable
//
this.toolStripMenuItem_Disable.Name = "toolStripMenuItem_Disable";
resources.ApplyResources(this.toolStripMenuItem_Disable, "toolStripMenuItem_Disable");
toolStripMenuItem_Disable.Name = "toolStripMenuItem_Disable";
resources.ApplyResources(toolStripMenuItem_Disable, "toolStripMenuItem_Disable");
//
// toolStripSeparator3
//
this.toolStripSeparator3.Name = "toolStripSeparator3";
resources.ApplyResources(this.toolStripSeparator3, "toolStripSeparator3");
toolStripSeparator3.Name = "toolStripSeparator3";
resources.ApplyResources(toolStripSeparator3, "toolStripSeparator3");
//
// toolStripMenuItem_Refresh
//
this.toolStripMenuItem_Refresh.Name = "toolStripMenuItem_Refresh";
resources.ApplyResources(this.toolStripMenuItem_Refresh, "toolStripMenuItem_Refresh");
toolStripMenuItem_Refresh.Name = "toolStripMenuItem_Refresh";
resources.ApplyResources(toolStripMenuItem_Refresh, "toolStripMenuItem_Refresh");
//
// toolStripMenuItem_FlushDnsCache
//
this.toolStripMenuItem_FlushDnsCache.Name = "toolStripMenuItem_FlushDnsCache";
resources.ApplyResources(this.toolStripMenuItem_FlushDnsCache, "toolStripMenuItem_FlushDnsCache");
toolStripMenuItem_FlushDnsCache.Name = "toolStripMenuItem_FlushDnsCache";
resources.ApplyResources(toolStripMenuItem_FlushDnsCache, "toolStripMenuItem_FlushDnsCache");
//
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
resources.ApplyResources(this.toolStripSeparator2, "toolStripSeparator2");
toolStripSeparator2.Name = "toolStripSeparator2";
resources.ApplyResources(toolStripSeparator2, "toolStripSeparator2");
//
// toolStripMenuItem_New
//
this.toolStripMenuItem_New.Name = "toolStripMenuItem_New";
resources.ApplyResources(this.toolStripMenuItem_New, "toolStripMenuItem_New");
toolStripMenuItem_New.Name = "toolStripMenuItem_New";
resources.ApplyResources(toolStripMenuItem_New, "toolStripMenuItem_New");
//
// toolStripMenuItem_Modify
//
this.toolStripMenuItem_Modify.Name = "toolStripMenuItem_Modify";
resources.ApplyResources(this.toolStripMenuItem_Modify, "toolStripMenuItem_Modify");
toolStripMenuItem_Modify.Name = "toolStripMenuItem_Modify";
resources.ApplyResources(toolStripMenuItem_Modify, "toolStripMenuItem_Modify");
//
// toolStripMenuItem_Delete
//
this.toolStripMenuItem_Delete.Name = "toolStripMenuItem_Delete";
resources.ApplyResources(this.toolStripMenuItem_Delete, "toolStripMenuItem_Delete");
toolStripMenuItem_Delete.Name = "toolStripMenuItem_Delete";
resources.ApplyResources(toolStripMenuItem_Delete, "toolStripMenuItem_Delete");
//
// toolStripSeparator1
//
this.toolStripSeparator1.Name = "toolStripSeparator1";
resources.ApplyResources(this.toolStripSeparator1, "toolStripSeparator1");
toolStripSeparator1.Name = "toolStripSeparator1";
resources.ApplyResources(toolStripSeparator1, "toolStripSeparator1");
//
// toolStripMenuItem_More
//
toolStripMenuItem_More.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { toolStripMenuItem_Import, toolStripMenuItem_Export, toolStripSeparator5, toolStripMenuItem_ResetWindowSize });
toolStripMenuItem_More.Name = "toolStripMenuItem_More";
resources.ApplyResources(toolStripMenuItem_More, "toolStripMenuItem_More");
//
// toolStripMenuItem_Import
//
toolStripMenuItem_Import.Name = "toolStripMenuItem_Import";
resources.ApplyResources(toolStripMenuItem_Import, "toolStripMenuItem_Import");
toolStripMenuItem_Import.Click += toolStripMenuItem_Import_Click;
//
// toolStripMenuItem_Export
//
toolStripMenuItem_Export.Name = "toolStripMenuItem_Export";
resources.ApplyResources(toolStripMenuItem_Export, "toolStripMenuItem_Export");
toolStripMenuItem_Export.Click += toolStripMenuItem_Export_Click;
//
// toolStripSeparator4
//
toolStripSeparator4.Name = "toolStripSeparator4";
resources.ApplyResources(toolStripSeparator4, "toolStripSeparator4");
//
// toolStripMenuItem_About
//
this.toolStripMenuItem_About.Name = "toolStripMenuItem_About";
resources.ApplyResources(this.toolStripMenuItem_About, "toolStripMenuItem_About");
toolStripMenuItem_About.Name = "toolStripMenuItem_About";
resources.ApplyResources(toolStripMenuItem_About, "toolStripMenuItem_About");
//
// imageListProxies
//
this.imageListProxies.ColorDepth = System.Windows.Forms.ColorDepth.Depth8Bit;
this.imageListProxies.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageListProxies.ImageStream")));
this.imageListProxies.TransparentColor = System.Drawing.Color.Transparent;
this.imageListProxies.Images.SetKeyName(0, "disable.png");
this.imageListProxies.Images.SetKeyName(1, "enable.png");
imageListProxies.ColorDepth = System.Windows.Forms.ColorDepth.Depth8Bit;
imageListProxies.ImageStream = (System.Windows.Forms.ImageListStreamer)resources.GetObject("imageListProxies.ImageStream");
imageListProxies.TransparentColor = System.Drawing.Color.Transparent;
imageListProxies.Images.SetKeyName(0, "disable.png");
imageListProxies.Images.SetKeyName(1, "enable.png");
//
// saveFileDialog_Export
//
resources.ApplyResources(saveFileDialog_Export, "saveFileDialog_Export");
//
// openFileDialog_Import
//
openFileDialog_Import.FileName = "openFileDialog1";
resources.ApplyResources(openFileDialog_Import, "openFileDialog_Import");
//
// toolStripMenuItem_ResetWindowSize
//
toolStripMenuItem_ResetWindowSize.Name = "toolStripMenuItem_ResetWindowSize";
resources.ApplyResources(toolStripMenuItem_ResetWindowSize, "toolStripMenuItem_ResetWindowSize");
toolStripMenuItem_ResetWindowSize.Click += toolStripMenuItem_ResetWindowSize_Click;
//
// toolStripSeparator5
//
toolStripSeparator5.Name = "toolStripSeparator5";
resources.ApplyResources(toolStripSeparator5, "toolStripSeparator5");
//
// PortProxyGUI
//
resources.ApplyResources(this, "$this");
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.listViewProxies);
this.Name = "PortProxyGUI";
this.Load += new System.EventHandler(this.PortProxyGUI_Load);
this.Shown += new System.EventHandler(this.PortProxyGUI_Shown);
this.contextMenuStrip1.ResumeLayout(false);
this.ResumeLayout(false);
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
Controls.Add(listViewProxies);
Name = "PortProxyGUI";
FormClosing += PortProxyGUI_FormClosing;
Load += PortProxyGUI_Load;
Shown += PortProxyGUI_Shown;
Resize += PortProxyGUI_Resize;
contextMenuStrip_RightClick.ResumeLayout(false);
ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ColumnHeader columnHeader2;
private System.Windows.Forms.ColumnHeader columnHeader3;
private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
private System.Windows.Forms.ContextMenuStrip contextMenuStrip_RightClick;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem_New;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem_Delete;
private System.Windows.Forms.ColumnHeader columnHeader4;
@ -224,6 +259,14 @@
private System.Windows.Forms.ColumnHeader columnHeader7;
internal System.Windows.Forms.ListView listViewProxies;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem_FlushDnsCache;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem_More;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem_Export;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem_Import;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator4;
private System.Windows.Forms.SaveFileDialog saveFileDialog_Export;
private System.Windows.Forms.OpenFileDialog openFileDialog_Import;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator5;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem_ResetWindowSize;
}
}

View File

@ -1,6 +1,11 @@
using NStandard;
using PortProxyGUI.Data;
using PortProxyGUI.UI;
using PortProxyGUI.Utils;
using System;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using static System.Windows.Forms.ListViewItem;
@ -9,21 +14,29 @@ namespace PortProxyGUI
{
public partial class PortProxyGUI : Form
{
private readonly ListViewColumnSorter lvwColumnSorter = new ListViewColumnSorter();
public SetProxy SetProxyForm;
public About AboutForm;
private ListViewColumnSorter lvwColumnSorter;
private AppConfig AppConfig;
public PortProxyGUI()
{
InitializeComponent();
Font = Util.UiFont;
Font = InterfaceUtil.UiFont;
lvwColumnSorter = new ListViewColumnSorter();
listViewProxies.ListViewItemSorter = lvwColumnSorter;
}
private void PortProxyGUI_Load(object sender, EventArgs e)
{
AppConfig = Program.Database.GetAppConfig();
var size = AppConfig.MainWindowSize;
Left -= (size.Width - Width) / 2;
Top -= (size.Height - Height) / 2;
ResetWindowSize();
}
private void PortProxyGUI_Shown(object sender, EventArgs e)
@ -31,6 +44,21 @@ namespace PortProxyGUI
RefreshProxyList();
}
private void ResetWindowSize()
{
Size = AppConfig.MainWindowSize;
if (AppConfig.PortProxyColumnWidths.Length != listViewProxies.Columns.Count)
{
Any.ReDim(ref AppConfig.PortProxyColumnWidths, listViewProxies.Columns.Count);
}
foreach (var (column, configWidth) in Any.Zip(listViewProxies.Columns.OfType<ColumnHeader>(), AppConfig.PortProxyColumnWidths))
{
column.Width = configWidth;
}
}
private Data.Rule ParseRule(ListViewItem item)
{
var subItems = item.SubItems.OfType<ListViewSubItem>().ToArray();
@ -62,7 +90,7 @@ namespace PortProxyGUI
try
{
var rule = ParseRule(item);
PortProxyUtil.AddOrUpdateProxy(rule);
PortPorxyUtil.AddOrUpdateProxy(rule);
}
catch (NotSupportedException ex)
{
@ -70,6 +98,7 @@ namespace PortProxyGUI
return;
}
}
PortPorxyUtil.ParamChange();
}
private void DisableSelectedProxies()
@ -82,7 +111,7 @@ namespace PortProxyGUI
try
{
var rule = ParseRule(item);
PortProxyUtil.DeleteProxy(rule);
PortPorxyUtil.DeleteProxy(rule);
}
catch (NotSupportedException ex)
{
@ -90,13 +119,14 @@ namespace PortProxyGUI
return;
}
}
PortPorxyUtil.ParamChange();
}
private void DeleteSelectedProxies()
{
var items = listViewProxies.SelectedItems.OfType<ListViewItem>();
DisableSelectedProxies();
Program.SqliteDbScope.RemoveRange(items.Select(x => new Data.Rule { Id = x.Tag.ToString() }));
Program.Database.RemoveRange(items.Select(x => new Data.Rule { Id = x.Tag.ToString() }));
foreach (var item in items) listViewProxies.Items.Remove(item);
}
@ -172,8 +202,8 @@ namespace PortProxyGUI
public void RefreshProxyList()
{
var proxies = PortProxyUtil.GetProxies();
var rules = Program.SqliteDbScope.Rules.ToArray();
var proxies = PortPorxyUtil.GetProxies();
var rules = Program.Database.Rules.ToArray();
foreach (var proxy in proxies)
{
var matchedRule = rules.FirstOrDefault(r => r.EqualsWithKeys(proxy));
@ -188,33 +218,19 @@ namespace PortProxyGUI
where proxy.Valid && proxy.Id is not null
select proxy;
Program.SqliteDbScope.AddRange(pendingAdds);
Program.SqliteDbScope.UpdateRange(pendingUpdates);
Program.Database.AddRange(pendingAdds);
Program.Database.UpdateRange(pendingUpdates);
rules = Program.SqliteDbScope.Rules.ToArray();
rules = Program.Database.Rules.ToArray();
InitProxyGroups(rules);
InitProxyItems(rules, proxies);
}
public void FlushDnsCache()
private void contextMenuStrip_RightClick_MouseClick(object sender, MouseEventArgs e)
{
try
if (sender is ContextMenuStrip strip)
{
CmdUtil.FlushDNSCache();
RefreshProxyList();
}
catch (NotSupportedException ex)
{
MessageBox.Show(ex.Message, "Exclamation", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}
}
private void contextMenuStrip1_MouseClick(object sender, MouseEventArgs e)
{
if (sender is ContextMenuStrip _sender)
{
var selected = _sender.Items.OfType<ToolStripMenuItem>().Where(x => x.Selected).FirstOrDefault();
var selected = strip.Items.OfType<ToolStripMenuItem>().Where(x => x.Selected).FirstOrDefault();
if (selected is null || !selected.Enabled) return;
switch (selected)
@ -238,7 +254,7 @@ namespace PortProxyGUI
RefreshProxyList();
break;
case ToolStripMenuItem item when item == toolStripMenuItem_FlushDnsCache:
FlushDnsCache();
DnsUtil.FlushCache();
break;
case ToolStripMenuItem item when item == toolStripMenuItem_Delete: DeleteSelectedProxies(); break;
@ -257,21 +273,21 @@ namespace PortProxyGUI
private void listView1_MouseUp(object sender, MouseEventArgs e)
{
if (sender is ListView _sender)
if (sender is ListView listView)
{
toolStripMenuItem_Enable.Enabled = e.Button == MouseButtons.Right && _sender.SelectedItems.OfType<ListViewItem>().Any(x => x.ImageIndex == 0);
toolStripMenuItem_Disable.Enabled = e.Button == MouseButtons.Right && _sender.SelectedItems.OfType<ListViewItem>().Any(x => x.ImageIndex == 1);
toolStripMenuItem_Enable.Enabled = e.Button == MouseButtons.Right && listView.SelectedItems.OfType<ListViewItem>().Any(x => x.ImageIndex == 0);
toolStripMenuItem_Disable.Enabled = e.Button == MouseButtons.Right && listView.SelectedItems.OfType<ListViewItem>().Any(x => x.ImageIndex == 1);
toolStripMenuItem_Delete.Enabled = e.Button == MouseButtons.Right && _sender.SelectedItems.OfType<ListViewItem>().Any();
toolStripMenuItem_Modify.Enabled = e.Button == MouseButtons.Right && _sender.SelectedItems.OfType<ListViewItem>().Count() == 1;
toolStripMenuItem_Delete.Enabled = e.Button == MouseButtons.Right && listView.SelectedItems.OfType<ListViewItem>().Any();
toolStripMenuItem_Modify.Enabled = e.Button == MouseButtons.Right && listView.SelectedItems.OfType<ListViewItem>().Count() == 1;
}
}
private void listView1_DoubleClick(object sender, EventArgs e)
{
if (sender is ListView _sender)
if (sender is ListView listView)
{
var selectAny = _sender.SelectedItems.OfType<ListViewItem>().Any();
var selectAny = listView.SelectedItems.OfType<ListViewItem>().Any();
if (selectAny)
{
if (SetProxyForm == null) SetProxyForm = new SetProxy(this);
@ -314,5 +330,69 @@ namespace PortProxyGUI
if (e.KeyCode == Keys.Delete) DeleteSelectedProxies();
}
}
private void listViewProxies_ColumnWidthChanged(object sender, ColumnWidthChangedEventArgs e)
{
if (AppConfig is not null && sender is ListView listView)
{
AppConfig.PortProxyColumnWidths[e.ColumnIndex] = listView.Columns[e.ColumnIndex].Width;
}
}
private void PortProxyGUI_FormClosing(object sender, FormClosingEventArgs e)
{
Program.Database.SaveAppConfig(AppConfig);
}
private void PortProxyGUI_Resize(object sender, EventArgs e)
{
if (AppConfig is not null && sender is Form form)
{
AppConfig.MainWindowSize = form.Size;
}
}
private void toolStripMenuItem_Export_Click(object sender, EventArgs e)
{
using var dialog = saveFileDialog_Export;
var result = dialog.ShowDialog();
if (result == DialogResult.OK)
{
var fileName = dialog.FileName;
File.Copy(ApplicationDbScope.AppDbFile, fileName, true);
}
}
private void toolStripMenuItem_Import_Click(object sender, EventArgs e)
{
using var dialog = openFileDialog_Import;
var result = dialog.ShowDialog();
if (result == DialogResult.OK)
{
var fileName = dialog.FileName;
using (var scope = ApplicationDbScope.FromFile(fileName))
{
foreach (var rule in scope.Rules)
{
var exsist = Program.Database.GetRule(rule.Type, rule.ListenOn, rule.ListenPort);
if (exsist is null)
{
rule.Id = Guid.NewGuid().ToString();
Program.Database.Add(rule);
}
}
}
RefreshProxyList();
}
}
private void toolStripMenuItem_ResetWindowSize_Click(object sender, EventArgs e)
{
AppConfig = new AppConfig();
ResetWindowSize();
}
}
}

View File

@ -14,7 +14,7 @@
<PackageTags>portproxy TCP/IP redirector</PackageTags>
<PackageLicenseFile>LICENSE.md</PackageLicenseFile>
<Copyright>Copyright © nstandard.net 2020</Copyright>
<Version>1.3.2</Version>
<Version>1.4.0</Version>
<ApplicationIcon>icon.ico</ApplicationIcon>
<ApplicationDefaultFont>Microsoft Sans Serif, 8pt</ApplicationDefaultFont>
<AssemblyName>PPGUI</AssemblyName>
@ -39,7 +39,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="SQLib.Sqlite" Version="0.8.6" />
<PackageReference Include="SQLib.Sqlite" Version="0.11.0" />
</ItemGroup>
</Project>

View File

@ -1,4 +1,64 @@
<root>
<?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">
@ -52,10 +112,10 @@
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="columnHeader1.Text" xml:space="preserve">
<value />
@ -98,82 +158,112 @@
<value>Comment</value>
</data>
<data name="columnHeader7.Width" type="System.Int32, mscorlib">
<value>104</value>
<value>100</value>
</data>
<metadata name="contextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="contextMenuStrip_RightClick.TrayLocation" type="System.Drawing.Point, System.Drawing">
<value>17, 17</value>
</data>
<data name="toolStripMenuItem_Enable.Size" type="System.Drawing.Size, System.Drawing">
<value>180, 22</value>
<value>174, 22</value>
</data>
<data name="toolStripMenuItem_Enable.Text" xml:space="preserve">
<value>Enable (&amp;E)</value>
</data>
<data name="toolStripMenuItem_Disable.Size" type="System.Drawing.Size, System.Drawing">
<value>180, 22</value>
<value>174, 22</value>
</data>
<data name="toolStripMenuItem_Disable.Text" xml:space="preserve">
<value>Disable (&amp;I)</value>
</data>
<data name="toolStripSeparator3.Size" type="System.Drawing.Size, System.Drawing">
<value>177, 6</value>
<value>171, 6</value>
</data>
<data name="toolStripMenuItem_Refresh.Size" type="System.Drawing.Size, System.Drawing">
<value>180, 22</value>
<value>174, 22</value>
</data>
<data name="toolStripMenuItem_Refresh.Text" xml:space="preserve">
<value>Refresh (&amp;F)</value>
</data>
<data name="toolStripMenuItem_FlushDnsCache.Size" type="System.Drawing.Size, System.Drawing">
<value>180, 22</value>
<value>174, 22</value>
</data>
<data name="toolStripMenuItem_FlushDnsCache.Text" xml:space="preserve">
<value>Flush DNS Cache</value>
</data>
<data name="toolStripMenuItem_FlushDnsCache.ToolTipText" xml:space="preserve">
<value>Will perform ipconfig/flushDNS</value>
<value>Perform ipconfig /flushDNS</value>
</data>
<data name="toolStripSeparator2.Size" type="System.Drawing.Size, System.Drawing">
<value>177, 6</value>
<value>171, 6</value>
</data>
<data name="toolStripMenuItem_New.Size" type="System.Drawing.Size, System.Drawing">
<value>180, 22</value>
<value>174, 22</value>
</data>
<data name="toolStripMenuItem_New.Text" xml:space="preserve">
<value>New (&amp;N) ...</value>
</data>
<data name="toolStripMenuItem_Modify.Size" type="System.Drawing.Size, System.Drawing">
<value>180, 22</value>
<value>174, 22</value>
</data>
<data name="toolStripMenuItem_Modify.Text" xml:space="preserve">
<value>Modify (&amp;M) ...</value>
</data>
<data name="toolStripMenuItem_Delete.Size" type="System.Drawing.Size, System.Drawing">
<value>180, 22</value>
<value>174, 22</value>
</data>
<data name="toolStripMenuItem_Delete.Text" xml:space="preserve">
<value>Delete (&amp;D)</value>
</data>
<data name="toolStripSeparator1.Size" type="System.Drawing.Size, System.Drawing">
<value>177, 6</value>
<value>171, 6</value>
</data>
<data name="toolStripMenuItem_Import.Size" type="System.Drawing.Size, System.Drawing">
<value>186, 22</value>
</data>
<data name="toolStripMenuItem_Import.Text" xml:space="preserve">
<value>Import</value>
</data>
<data name="toolStripMenuItem_Export.Size" type="System.Drawing.Size, System.Drawing">
<value>186, 22</value>
</data>
<data name="toolStripMenuItem_Export.Text" xml:space="preserve">
<value>Export</value>
</data>
<data name="toolStripSeparator5.Size" type="System.Drawing.Size, System.Drawing">
<value>183, 6</value>
</data>
<data name="toolStripMenuItem_ResetWindowSize.Size" type="System.Drawing.Size, System.Drawing">
<value>186, 22</value>
</data>
<data name="toolStripMenuItem_ResetWindowSize.Text" xml:space="preserve">
<value>Reset Window</value>
</data>
<data name="toolStripMenuItem_More.Size" type="System.Drawing.Size, System.Drawing">
<value>174, 22</value>
</data>
<data name="toolStripMenuItem_More.Text" xml:space="preserve">
<value>More</value>
</data>
<data name="toolStripSeparator4.Size" type="System.Drawing.Size, System.Drawing">
<value>171, 6</value>
</data>
<data name="toolStripMenuItem_About.Size" type="System.Drawing.Size, System.Drawing">
<value>180, 22</value>
<value>174, 22</value>
</data>
<data name="toolStripMenuItem_About.Text" xml:space="preserve">
<value>About</value>
</data>
<data name="contextMenuStrip1.Size" type="System.Drawing.Size, System.Drawing">
<value>181, 220</value>
<data name="contextMenuStrip_RightClick.Size" type="System.Drawing.Size, System.Drawing">
<value>175, 226</value>
</data>
<data name="&gt;&gt;contextMenuStrip1.Name" xml:space="preserve">
<value>contextMenuStrip1</value>
<data name="&gt;&gt;contextMenuStrip_RightClick.Name" xml:space="preserve">
<value>contextMenuStrip_RightClick</value>
</data>
<data name="&gt;&gt;contextMenuStrip1.Type" xml:space="preserve">
<data name="&gt;&gt;contextMenuStrip_RightClick.Type" xml:space="preserve">
<value>System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="listViewProxies.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
@ -187,54 +277,54 @@
<value>4, 3, 4, 3</value>
</data>
<data name="listViewProxies.Size" type="System.Drawing.Size, System.Drawing">
<value>704, 456</value>
<value>704, 461</value>
</data>
<data name="imageListProxies.TrayLocation" type="System.Drawing.Point, System.Drawing">
<value>239, 17</value>
</data>
<metadata name="imageListProxies.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>182, 17</value>
</metadata>
<data name="imageListProxies.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAA3AgAAAJNU0Z0AUkBTAIBAQIB
AAEwAQEBMAEBARABAAEQAQAE/wEJAQAI/wFCAU0BNgEEBgABNgEEAgABKAMAAUADAAEQAwABAQEAAQgG
AAEEGAABgAIAAYADAAKAAQABgAMAAYABAAGAAQACgAIAA8ABAAHAAdwBwAEAAfABygGmAQABMwUAATMB
AAEzAQABMwEAAjMCAAMWAQADHAEAAyIBAAMpAQADVQEAA00BAANCAQADOQEAAYABfAH/AQACUAH/AQAB
kwEAAdYBAAH/AewBzAEAAcYB1gHvAQAB1gLnAQABkAGpAa0CAAH/ATMDAAFmAwABmQMAAcwCAAEzAwAC
MwIAATMBZgIAATMBmQIAATMBzAIAATMB/wIAAWYDAAFmATMCAAJmAgABZgGZAgABZgHMAgABZgH/AgAB
mQMAAZkBMwIAAZkBZgIAApkCAAGZAcwCAAGZAf8CAAHMAwABzAEzAgABzAFmAgABzAGZAgACzAIAAcwB
/wIAAf8BZgIAAf8BmQIAAf8BzAEAATMB/wIAAf8BAAEzAQABMwEAAWYBAAEzAQABmQEAATMBAAHMAQAB
MwEAAf8BAAH/ATMCAAMzAQACMwFmAQACMwGZAQACMwHMAQACMwH/AQABMwFmAgABMwFmATMBAAEzAmYB
AAEzAWYBmQEAATMBZgHMAQABMwFmAf8BAAEzAZkCAAEzAZkBMwEAATMBmQFmAQABMwKZAQABMwGZAcwB
AAEzAZkB/wEAATMBzAIAATMBzAEzAQABMwHMAWYBAAEzAcwBmQEAATMCzAEAATMBzAH/AQABMwH/ATMB
AAEzAf8BZgEAATMB/wGZAQABMwH/AcwBAAEzAv8BAAFmAwABZgEAATMBAAFmAQABZgEAAWYBAAGZAQAB
ZgEAAcwBAAFmAQAB/wEAAWYBMwIAAWYCMwEAAWYBMwFmAQABZgEzAZkBAAFmATMBzAEAAWYBMwH/AQAC
ZgIAAmYBMwEAA2YBAAJmAZkBAAJmAcwBAAFmAZkCAAFmAZkBMwEAAWYBmQFmAQABZgKZAQABZgGZAcwB
AAFmAZkB/wEAAWYBzAIAAWYBzAEzAQABZgHMAZkBAAFmAswBAAFmAcwB/wEAAWYB/wIAAWYB/wEzAQAB
ZgH/AZkBAAFmAf8BzAEAAcwBAAH/AQAB/wEAAcwBAAKZAgABmQEzAZkBAAGZAQABmQEAAZkBAAHMAQAB
mQMAAZkCMwEAAZkBAAFmAQABmQEzAcwBAAGZAQAB/wEAAZkBZgIAAZkBZgEzAQABmQEzAWYBAAGZAWYB
mQEAAZkBZgHMAQABmQEzAf8BAAKZATMBAAKZAWYBAAOZAQACmQHMAQACmQH/AQABmQHMAgABmQHMATMB
AAFmAcwBZgEAAZkBzAGZAQABmQLMAQABmQHMAf8BAAGZAf8CAAGZAf8BMwEAAZkBzAFmAQABmQH/AZkB
AAGZAf8BzAEAAZkC/wEAAcwDAAGZAQABMwEAAcwBAAFmAQABzAEAAZkBAAHMAQABzAEAAZkBMwIAAcwC
MwEAAcwBMwFmAQABzAEzAZkBAAHMATMBzAEAAcwBMwH/AQABzAFmAgABzAFmATMBAAGZAmYBAAHMAWYB
mQEAAcwBZgHMAQABmQFmAf8BAAHMAZkCAAHMAZkBMwEAAcwBmQFmAQABzAKZAQABzAGZAcwBAAHMAZkB
/wEAAswCAALMATMBAALMAWYBAALMAZkBAAPMAQACzAH/AQABzAH/AgABzAH/ATMBAAGZAf8BZgEAAcwB
/wGZAQABzAH/AcwBAAHMAv8BAAHMAQABMwEAAf8BAAFmAQAB/wEAAZkBAAHMATMCAAH/AjMBAAH/ATMB
ZgEAAf8BMwGZAQAB/wEzAcwBAAH/ATMB/wEAAf8BZgIAAf8BZgEzAQABzAJmAQAB/wFmAZkBAAH/AWYB
zAEAAcwBZgH/AQAB/wGZAgAB/wGZATMBAAH/AZkBZgEAAf8CmQEAAf8BmQHMAQAB/wGZAf8BAAH/AcwC
AAH/AcwBMwEAAf8BzAFmAQAB/wHMAZkBAAH/AswBAAH/AcwB/wEAAv8BMwEAAcwB/wFmAQAC/wGZAQAC
/wHMAQACZgH/AQABZgH/AWYBAAFmAv8BAAH/AmYBAAH/AWYB/wEAAv8BZgEAASEBAAGlAQADXwEAA3cB
AAOGAQADlgEAA8sBAAOyAQAD1wEAA90BAAPjAQAD6gEAA/EBAAP4AQAB8AH7Af8BAAGkAqABAAOAAwAB
/wIAAf8DAAL/AQAB/wMAAf8BAAH/AQAC/wIAA/8EAAr0NAAB/wGUChcBlAH/AgAB/wG6CpUBugH/IgAB
lAwXAZQCAAG6DJUBuiIADhcCAA6VIgAEFwEWAfQC/wH0ARYEFwIADpUiAAMXARYB/wG9ARYBlAH0Af8B
FgMXAgAFlQK7B5UiAAMXAfQBvQIXAZQB/wL0AxcCAASVAboC/wHBBpUiAAMXAf8BFgEXAZQB/wKUAf8D
FwIAA5UBugH/AcEBugH/AcEFlSIAAxcB/wKUAf8BlAEXARYB/wMXAgADlQH/AcEClQG6Af8BwQSVIgAD
FwL0Af8BlAIXAb0B9AMXAgAIlQG6Af8BwQOVIgADFwEWAf8B9AGUARYBvQH/ARYDFwIACZUBugH/A5Ui
AAQXARYB9AL/AfQBFgQXAf8BAA6VAf8hAA4XAf8BAA6VAf8hAAGUDBcBlAIAAboMlQG6IgAB/wGUChcB
lAH/AgAB/wG6CpUBugH/NAAB/wj0JAABQgFNAT4HAAE+AwABKAMAAUADAAEQAwABAQEAAQEFAAGAFwAD
/wEAAeABBwL/BAABgAEBAYABAQQAAYABAQGAAQEEAAGAAQEBgAEBBAABgAEBAYABAQQAAYABAQGAAQEE
AAGAAQEBgAEBBAABgAEBAYABAQQAAYABAQGAAQEEAAGAAQEBgAEBBAABgAEBAYABAQQAAYABAAGABQAB
gAEAAYAFAAGAAQEBgAEBBAABgAEBAYABAQQAAv8B4AEPBAAL
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADc
CAAAAk1TRnQBSQFMAgEBAgEAAYwBAQGQAQEBEAEAARABAAT/AQkBEAj/AUIBTQE2AQQGAAE2AQQCAAEo
AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA
AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm
AZkCAAFmAcwCAAFmAf8CAAGZAwABmQEzAgABmQFmAgACmQIAAZkBzAIAAZkB/wIAAcwDAAHMATMCAAHM
AWYCAAHMAZkCAALMAgABzAH/AgAB/wFmAgAB/wGZAgAB/wHMAQABMwH/AgAB/wEAATMBAAEzAQABZgEA
ATMBAAGZAQABMwEAAcwBAAEzAQAB/wEAAf8BMwIAAzMBAAIzAWYBAAIzAZkBAAIzAcwBAAIzAf8BAAEz
AWYCAAEzAWYBMwEAATMCZgEAATMBZgGZAQABMwFmAcwBAAEzAWYB/wEAATMBmQIAATMBmQEzAQABMwGZ
AWYBAAEzApkBAAEzAZkBzAEAATMBmQH/AQABMwHMAgABMwHMATMBAAEzAcwBZgEAATMBzAGZAQABMwLM
AQABMwHMAf8BAAEzAf8BMwEAATMB/wFmAQABMwH/AZkBAAEzAf8BzAEAATMC/wEAAWYDAAFmAQABMwEA
AWYBAAFmAQABZgEAAZkBAAFmAQABzAEAAWYBAAH/AQABZgEzAgABZgIzAQABZgEzAWYBAAFmATMBmQEA
AWYBMwHMAQABZgEzAf8BAAJmAgACZgEzAQADZgEAAmYBmQEAAmYBzAEAAWYBmQIAAWYBmQEzAQABZgGZ
AWYBAAFmApkBAAFmAZkBzAEAAWYBmQH/AQABZgHMAgABZgHMATMBAAFmAcwBmQEAAWYCzAEAAWYBzAH/
AQABZgH/AgABZgH/ATMBAAFmAf8BmQEAAWYB/wHMAQABzAEAAf8BAAH/AQABzAEAApkCAAGZATMBmQEA
AZkBAAGZAQABmQEAAcwBAAGZAwABmQIzAQABmQEAAWYBAAGZATMBzAEAAZkBAAH/AQABmQFmAgABmQFm
ATMBAAGZATMBZgEAAZkBZgGZAQABmQFmAcwBAAGZATMB/wEAApkBMwEAApkBZgEAA5kBAAKZAcwBAAKZ
Af8BAAGZAcwCAAGZAcwBMwEAAWYBzAFmAQABmQHMAZkBAAGZAswBAAGZAcwB/wEAAZkB/wIAAZkB/wEz
AQABmQHMAWYBAAGZAf8BmQEAAZkB/wHMAQABmQL/AQABzAMAAZkBAAEzAQABzAEAAWYBAAHMAQABmQEA
AcwBAAHMAQABmQEzAgABzAIzAQABzAEzAWYBAAHMATMBmQEAAcwBMwHMAQABzAEzAf8BAAHMAWYCAAHM
AWYBMwEAAZkCZgEAAcwBZgGZAQABzAFmAcwBAAGZAWYB/wEAAcwBmQIAAcwBmQEzAQABzAGZAWYBAAHM
ApkBAAHMAZkBzAEAAcwBmQH/AQACzAIAAswBMwEAAswBZgEAAswBmQEAA8wBAALMAf8BAAHMAf8CAAHM
Af8BMwEAAZkB/wFmAQABzAH/AZkBAAHMAf8BzAEAAcwC/wEAAcwBAAEzAQAB/wEAAWYBAAH/AQABmQEA
AcwBMwIAAf8CMwEAAf8BMwFmAQAB/wEzAZkBAAH/ATMBzAEAAf8BMwH/AQAB/wFmAgAB/wFmATMBAAHM
AmYBAAH/AWYBmQEAAf8BZgHMAQABzAFmAf8BAAH/AZkCAAH/AZkBMwEAAf8BmQFmAQAB/wKZAQAB/wGZ
AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz
AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm
AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw
AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD/wQACvQ0AAH/AZQKFwGU
Af8CAAH/AboKlQG6Af8iAAGUDBcBlAIAAboMlQG6IgAOFwIADpUiAAQXARYB9AL/AfQBFgQXAgAOlSIA
AxcBFgH/Ab0BFgGUAfQB/wEWAxcCAAWVArsHlSIAAxcB9AG9AhcBlAH/AvQDFwIABJUBugL/AcEGlSIA
AxcB/wEWARcBlAH/ApQB/wMXAgADlQG6Af8BwQG6Af8BwQWVIgADFwH/ApQB/wGUARcBFgH/AxcCAAOV
Af8BwQKVAboB/wHBBJUiAAMXAvQB/wGUAhcBvQH0AxcCAAiVAboB/wHBA5UiAAMXARYB/wH0AZQBFgG9
Af8BFgMXAgAJlQG6Af8DlSIABBcBFgH0Av8B9AEWBBcB/wEADpUB/yEADhcB/wEADpUB/yEAAZQMFwGU
AgABugyVAboiAAH/AZQKFwGUAf8CAAH/AboKlQG6Af80AAH/CPQkAAFCAU0BPgcAAT4DAAEoAwABQAMA
ARADAAEBAQABAQUAAYAXAAP/AQAB4AEHAv8EAAGAAQEBgAEBBAABgAEBAYABAQQAAYABAQGAAQEEAAGA
AQEBgAEBBAABgAEBAYABAQQAAYABAQGAAQEEAAGAAQEBgAEBBAABgAEBAYABAQQAAYABAQGAAQEEAAGA
AQEBgAEBBAABgAEAAYAFAAGAAQABgAUAAYABAQGAAQEEAAGAAQEBgAEBBAAC/wHgAQ8aAAs=
</value>
</data>
<data name="listViewProxies.TabIndex" type="System.Int32, mscorlib">
@ -252,14 +342,26 @@
<data name="&gt;&gt;listViewProxies.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<data name="saveFileDialog_Export.TrayLocation" type="System.Drawing.Point, System.Drawing">
<value>389, 17</value>
</data>
<data name="saveFileDialog_Export.Filter" xml:space="preserve">
<value>Database File|*.db</value>
</data>
<data name="openFileDialog_Import.TrayLocation" type="System.Drawing.Point, System.Drawing">
<value>569, 17</value>
</data>
<data name="openFileDialog_Import.Filter" xml:space="preserve">
<value>Database File|*.db</value>
</data>
<data name="$this.Localizable" type="System.Boolean, mscorlib">
<value>True</value>
</metadata>
</data>
<data name="$this.AutoScaleDimensions" type="System.Drawing.SizeF, System.Drawing">
<value>6, 13</value>
</data>
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
<value>704, 456</value>
<value>704, 461</value>
</data>
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
@ -2530,6 +2632,30 @@
<data name="&gt;&gt;toolStripSeparator1.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;toolStripMenuItem_More.Name" xml:space="preserve">
<value>toolStripMenuItem_More</value>
</data>
<data name="&gt;&gt;toolStripMenuItem_More.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;toolStripMenuItem_Import.Name" xml:space="preserve">
<value>toolStripMenuItem_Import</value>
</data>
<data name="&gt;&gt;toolStripMenuItem_Import.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;toolStripMenuItem_Export.Name" xml:space="preserve">
<value>toolStripMenuItem_Export</value>
</data>
<data name="&gt;&gt;toolStripMenuItem_Export.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;toolStripSeparator4.Name" xml:space="preserve">
<value>toolStripSeparator4</value>
</data>
<data name="&gt;&gt;toolStripSeparator4.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;toolStripMenuItem_About.Name" xml:space="preserve">
<value>toolStripMenuItem_About</value>
</data>
@ -2542,6 +2668,30 @@
<data name="&gt;&gt;imageListProxies.Type" xml:space="preserve">
<value>System.Windows.Forms.ImageList, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;saveFileDialog_Export.Name" xml:space="preserve">
<value>saveFileDialog_Export</value>
</data>
<data name="&gt;&gt;saveFileDialog_Export.Type" xml:space="preserve">
<value>System.Windows.Forms.SaveFileDialog, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;openFileDialog_Import.Name" xml:space="preserve">
<value>openFileDialog_Import</value>
</data>
<data name="&gt;&gt;openFileDialog_Import.Type" xml:space="preserve">
<value>System.Windows.Forms.OpenFileDialog, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;toolStripMenuItem_ResetWindowSize.Name" xml:space="preserve">
<value>toolStripMenuItem_ResetWindowSize</value>
</data>
<data name="&gt;&gt;toolStripMenuItem_ResetWindowSize.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;toolStripSeparator5.Name" xml:space="preserve">
<value>toolStripSeparator5</value>
</data>
<data name="&gt;&gt;toolStripSeparator5.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;$this.Name" xml:space="preserve">
<value>PortProxyGUI</value>
</data>

View File

@ -112,15 +112,15 @@
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="columnHeader1.Text" xml:space="preserve">
<value />
</data>
<assembly alias="mscorlib" name="mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<assembly alias="mscorlib" name="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="columnHeader1.Width" type="System.Int32, mscorlib">
<value>24</value>
</data>
@ -160,7 +160,7 @@
<data name="columnHeader7.Width" type="System.Int32, mscorlib">
<value>104</value>
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="contextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing">
<value>17, 17</value>
</data>
@ -173,7 +173,7 @@
<data name="&gt;&gt;contextMenuStrip1.Type" xml:space="preserve">
<value>System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="listViewProxies.Dock" type="System.Windows.Forms.DockStyle, System.Windows.Forms">
<value>Fill</value>
</data>
@ -194,10 +194,10 @@
</data>
<data name="imageListProxies.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADc
CAAAAk1TRnQBSQFMAgEBAgEAASABAQEkAQEBEAEAARABAAT/AQkBEAj/AUIBTQE2AQQGAAE2AQQCAAEo
CAAAAk1TRnQBSQFMAgEBAgEAASABAQEwAQEBEAEAARABAAT/AQkBEAj/AUIBTQE2AQQGAAE2AQQCAAEo
AwABQAMAARADAAEBAQABCAYAAQQYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA
@ -2593,4 +2593,22 @@
<data name="&gt;&gt;$this.Type" xml:space="preserve">
<value>System.Windows.Forms.Form, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="toolStripMenuItem_FlushDnsCache.Text" xml:space="preserve">
<value>清理 DNS 缓存</value>
</data>
<data name="toolStripMenuItem_FlushDnsCache.ToolTipText" xml:space="preserve">
<value>执行 ipconfig /flushDNS</value>
</data>
<data name="toolStripMenuItem_Export.Text" xml:space="preserve">
<value>导出</value>
</data>
<data name="toolStripMenuItem_Import.Text" xml:space="preserve">
<value>导入</value>
</data>
<data name="toolStripMenuItem_More.Text" xml:space="preserve">
<value>更多</value>
</data>
<data name="toolStripMenuItem_ResetWindowSize.Text" xml:space="preserve">
<value>重置窗口</value>
</data>
</root>

View File

@ -1,12 +1,15 @@
using PortProxyGUI.Data;
using System;
using System.Globalization;
using System.IO;
using System.Threading;
using System.Windows.Forms;
namespace PortProxyGUI
{
static class Program
{
public static readonly ApplicationDbScope SqliteDbScope = ApplicationDbScope.UseDefault();
public static readonly ApplicationDbScope Database = ApplicationDbScope.FromFile(ApplicationDbScope.AppDbFile);
/// <summary>
/// The main entry point for the application.
@ -14,8 +17,6 @@ namespace PortProxyGUI
[STAThread]
static void Main()
{
SqliteDbScope.Migrate();
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
#if NET6_0_OR_GREATER

View File

@ -1,5 +1,6 @@
using NStandard;
using PortProxyGUI.Data;
using PortProxyGUI.Utils;
using System;
using System.Drawing;
using System.Linq;
@ -22,7 +23,7 @@ namespace PortProxyGUI
ParentWindow = parent;
InitializeComponent();
Font = Util.UiFont;
Font = InterfaceUtil.UiFont;
AutoTypeString = comboBox_Type.Text = comboBox_Type.Items.OfType<string>().First();
var groupNames = (
@ -115,22 +116,23 @@ namespace PortProxyGUI
if (_updateMode)
{
var oldRule = Program.SqliteDbScope.GetRule(_itemRule.Type, _itemRule.ListenOn, _itemRule.ListenPort);
PortProxyUtil.DeleteProxy(oldRule);
Program.SqliteDbScope.Remove(oldRule);
var oldRule = Program.Database.GetRule(_itemRule.Type, _itemRule.ListenOn, _itemRule.ListenPort);
PortPorxyUtil.DeleteProxy(oldRule);
Program.Database.Remove(oldRule);
PortProxyUtil.AddOrUpdateProxy(rule);
Program.SqliteDbScope.Add(rule);
PortPorxyUtil.AddOrUpdateProxy(rule);
Program.Database.Add(rule);
ParentWindow.UpdateListViewItem(_listViewItem, rule, 1);
}
else
{
PortProxyUtil.AddOrUpdateProxy(rule);
Program.SqliteDbScope.Add(rule);
PortPorxyUtil.AddOrUpdateProxy(rule);
Program.Database.Add(rule);
ParentWindow.RefreshProxyList();
}
PortPorxyUtil.ParamChange();
Close();
}

View File

@ -1,7 +1,7 @@
using System.Collections;
using System.Windows.Forms;
namespace PortProxyGUI
namespace PortProxyGUI.UI
{
public class ListViewColumnSorter : IComparer
{
@ -68,7 +68,7 @@ namespace PortProxyGUI
else if (OrderOfSort == SortOrder.Descending)
{
// Descending sort is selected, return negative result of compare operation
return (-compareResult);
return -compareResult;
}
else
{

View File

@ -0,0 +1,18 @@
using System;
using System.Runtime.InteropServices;
namespace PortProxyGUI.Utils
{
internal class DnsUtil
{
[DllImport("dnsapi.dll", EntryPoint = "DnsFlushResolverCache")]
static extern uint DnsFlushResolverCache();
public static void FlushCache()
{
var status = DnsFlushResolverCache();
if (status == 0) throw new InvalidOperationException("Flush DNS Cache failed.");
}
}
}

View File

@ -3,9 +3,9 @@ using System.Collections.Generic;
using System.Drawing;
using System.Text;
namespace PortProxyGUI
namespace PortProxyGUI.Utils
{
public class Util
public class InterfaceUtil
{
/// <summary>
/// Compatibility between .NET Framework and .NET Core.
@ -15,3 +15,4 @@ namespace PortProxyGUI
}
}

View File

@ -0,0 +1,114 @@
using Microsoft.Win32;
using PortProxyGUI.Data;
using PortProxyGUI.Native;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
namespace PortProxyGUI.Utils
{
public static class PortPorxyUtil
{
private static InvalidOperationException InvalidPortProxyType(string type) => new($"Invalid port proxy type ({type}).");
private static readonly string[] ProxyTypes = new[] { "v4tov4", "v4tov6", "v6tov4", "v6tov6" };
private static string GetKeyName(string type)
{
return $@"SYSTEM\CurrentControlSet\Services\PortProxy\{type}\tcp";
}
public static Rule[] GetProxies()
{
var ruleList = new List<Rule>();
foreach (var type in ProxyTypes)
{
var keyName = GetKeyName(type);
var key = Registry.LocalMachine.OpenSubKey(keyName);
if (key is not null)
{
foreach (var name in key.GetValueNames())
{
var listenParts = name.Split('/');
var listenOn = listenParts[0];
if (!int.TryParse(listenParts[1], out var listenPort)) continue;
var connectParts = key.GetValue(name).ToString().Split('/');
var connectTo = connectParts[0];
if (!int.TryParse(connectParts[1], out var connectPort)) continue;
ruleList.Add(new Rule
{
Type = type,
ListenOn = listenOn,
ListenPort = listenPort,
ConnectTo = connectTo,
ConnectPort = connectPort,
});
}
}
}
return ruleList.ToArray();
}
public static void AddOrUpdateProxy(Rule rule)
{
// $"netsh interface portproxy add {rule.Type} listenaddress={rule.ListenOn} listenport={rule.ListenPort} connectaddress={rule.ConnectTo} connectport={rule.ConnectPort}"
if (!ProxyTypes.Contains(rule.Type)) throw InvalidPortProxyType(rule.Type);
var keyName = GetKeyName(rule.Type);
var key = Registry.LocalMachine.OpenSubKey(keyName, true);
var name = $"{rule.ListenOn}/{rule.ListenPort}";
var value = $"{rule.ConnectTo}/{rule.ConnectPort}";
if (key is null) Registry.LocalMachine.CreateSubKey(keyName);
key = Registry.LocalMachine.OpenSubKey(keyName, true);
key?.SetValue(name, value);
}
public static void DeleteProxy(Rule rule)
{
// $"netsh interface portproxy delete {rule.Type} listenaddress={rule.ListenOn} listenport={rule.ListenPort}"
if (!ProxyTypes.Contains(rule.Type)) throw InvalidPortProxyType(rule.Type);
var keyName = GetKeyName(rule.Type);
var key = Registry.LocalMachine.OpenSubKey(keyName, true);
var name = $"{rule.ListenOn}/{rule.ListenPort}";
try
{
key?.DeleteValue(name);
}
catch { }
}
public static void ParamChange()
{
var hManager = NativeMethods.OpenSCManager(null, null, (uint)GenericRights.GENERIC_READ);
if (hManager == IntPtr.Zero) throw new InvalidOperationException("Open SC Manager failed.");
var serviceName = "iphlpsvc";
var hService = NativeMethods.OpenService(hManager, serviceName, ServiceRights.SERVICE_PAUSE_CONTINUE);
if (hService == IntPtr.Zero)
{
NativeMethods.CloseServiceHandle(hManager);
throw new InvalidOperationException($"Open Service ({serviceName}) failed.");
}
var serviceStatus = new ServiceStatus();
var success = NativeMethods.ControlService(hService, ServiceControls.SERVICE_CONTROL_PARAMCHANGE, ref serviceStatus);
NativeMethods.CloseServiceHandle(hService);
NativeMethods.CloseServiceHandle(hManager);
if (!success)
{
throw new InvalidOperationException($"Control Service ({serviceName}) ParamChange failed.");
}
}
}
}

View File

@ -1,27 +0,0 @@
using System;
using System.Diagnostics;
namespace PortProxyGUI
{
[Obsolete("The method of creating a new process is no longer used.")]
public static class CmdRunner
{
public static string Execute(string cmd)
{
var proc = Process.Start(new ProcessStartInfo
{
FileName = "cmd",
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
CreateNoWindow = true,
});
proc.Start();
proc.StandardInput.WriteLine($"{cmd} & exit");
var output = proc.StandardOutput.ReadToEnd();
return output;
}
}
}

View File

@ -1,89 +0,0 @@
using NStandard;
using PortProxyGUI.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace PortProxyGUI
{
[Obsolete("The method of creating a new process is no longer used.", true)]
public static class CmdUtil
{
private static Regex GetRegex(string fromType, string toType)
{
return new Regex($@"{fromType}[^:]*:[^\n]+?{toType}[^:]*:\r\n\r\n.+?\r\n--------------- ---------- --------------- ----------\r\n(.+?)\r\n\r\n", RegexOptions.Singleline);
}
private static readonly Dictionary<string, Regex> RegexList = new Dictionary<string, Regex>()
{
["ipv4 to ipv4"] = GetRegex("ipv4", "ipv4"),
["ipv4 to ipv6"] = GetRegex("ipv4", "ipv6"),
["ipv6 to ipv4"] = GetRegex("ipv6", "ipv4"),
["ipv6 to ipv6"] = GetRegex("ipv6", "ipv6"),
};
private static readonly Regex LineRegex = new(@"^(.*?)\s{1,}(.*?)\s{1,}(.*?)\s{1,}(.*?)$");
public static Rule[] GetProxies()
{
var output = CmdRunner.Execute("netsh interface portproxy show all");
var types = new[]
{
new ProxyType("ipv4", "ipv4"),
new ProxyType("ipv4", "ipv6"),
new ProxyType("ipv6", "ipv4"),
new ProxyType("ipv6", "ipv6"),
};
var list = new List<Rule>();
foreach (var type in types)
{
var regex = RegexList[$"{type.From} to {type.To}"];
var settings = output.ExtractFirst(regex);
var lines = settings?.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
if (lines is not null)
{
foreach (var line in lines)
{
if (line.TryResolve(LineRegex, out var parts))
{
var realListenPort = parts[2].First();
var realConnectPort = parts[4].First();
_ = int.TryParse(realListenPort, out var listenPort);
_ = int.TryParse(realConnectPort, out var connectPort);
list.Add(new Rule
{
Type = type.Type,
ListenOn = parts[1].First(),
ListenPort = listenPort,
ConnectTo = parts[3].First(),
ConnectPort = connectPort,
});
}
}
}
}
return list.ToArray();
}
public static void AddOrUpdateProxy(Rule rule)
{
CmdRunner.Execute($"netsh interface portproxy add {rule.Type} listenaddress={rule.ListenOn} listenport={rule.ListenPort} connectaddress={rule.ConnectTo} connectport={rule.ConnectPort}");
}
public static void DeleteProxy(Rule rule)
{
CmdRunner.Execute($"netsh interface portproxy delete {rule.Type} listenaddress={rule.ListenOn} listenport={rule.ListenPort}");
}
public static string FlushDNSCache()
{
return CmdRunner.Execute("ipconfig /flushdns");
}
}
}

View File

@ -1,71 +0,0 @@
using Microsoft.Win32;
using PortProxyGUI.Data;
using System;
using System.Collections.Generic;
using System.Linq;
namespace PortProxyGUI
{
public static class PortProxyUtil
{
private static InvalidOperationException InvalidPortProxyType(string type) => new($"Invalid port proxy type ({type}).");
private static readonly string[] ProxyTypes = new[] { "v4tov4", "v4tov6", "v6tov4", "v6tov6" };
public static Rule[] GetProxies()
{
var ruleList = new List<Rule>();
foreach (var type in ProxyTypes)
{
var keyName = $@"SYSTEM\ControlSet001\Services\PortProxy\{type}\tcp";
var key = Registry.LocalMachine.OpenSubKey(keyName);
if (key is not null)
{
foreach (var name in key.GetValueNames())
{
var listenParts = name.Split('/');
var listenOn = listenParts[0];
if (!int.TryParse(listenParts[1], out var listenPort)) continue;
var connectParts = key.GetValue(name).ToString().Split('/');
var connectTo = connectParts[0];
if (!int.TryParse(connectParts[1], out var connectPort)) continue;
ruleList.Add(new Rule
{
Type = type,
ListenOn = listenOn,
ListenPort = listenPort,
ConnectTo = connectTo,
ConnectPort = connectPort,
});
}
}
}
return ruleList.ToArray();
}
public static void AddOrUpdateProxy(Rule rule)
{
if (!ProxyTypes.Contains(rule.Type)) throw InvalidPortProxyType(rule.Type);
var keyName = $@"SYSTEM\ControlSet001\Services\PortProxy\{rule.Type}\tcp";
var key = Registry.LocalMachine.OpenSubKey(keyName, true);
var valueName = $"{rule.ListenOn}/{rule.ListenPort}";
var value = $"{rule.ConnectTo}/{rule.ConnectPort}";
key.SetValue(valueName, value);
}
public static void DeleteProxy(Rule rule)
{
if (!ProxyTypes.Contains(rule.Type)) throw InvalidPortProxyType(rule.Type);
var keyName = $@"SYSTEM\ControlSet001\Services\PortProxy\{rule.Type}\tcp";
var key = Registry.LocalMachine.OpenSubKey(keyName, true);
var valueName = $"{rule.ListenOn}/{rule.ListenPort}";
key.DeleteValue(valueName);
}
}
}

View File

@ -1,28 +0,0 @@
using System;
namespace PortProxyGUI
{
public class ProxyType
{
public ProxyType(string from, string to)
{
From = from;
To = to;
}
public string From { get; set; }
public string To { get; set; }
public string Type
{
get
{
if (From == "ipv4" && To == "ipv4") return "v4tov4";
if (From == "ipv4" && To == "ipv6") return "v4tov6";
if (From == "ipv6" && To == "ipv4") return "v6tov4";
if (From == "ipv6" && To == "ipv6") return "v6tov6";
throw new NotSupportedException();
}
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 17 KiB