From 9fc03d55e2909ec198406697fd684b22abae0ad8 Mon Sep 17 00:00:00 2001
From: JanitorialMess <65749353+JanitorialMess@users.noreply.github.com>
Date: Sun, 29 Mar 2026 16:36:02 -0400
Subject: [PATCH 1/6] refactor: use COM API for windows firewall rules
---
ServerPickerX/ServerPickerX.csproj | 2 +
.../SystemFirewalls/WindowsFirewallService.cs | 158 +++++++++++-------
2 files changed, 103 insertions(+), 57 deletions(-)
diff --git a/ServerPickerX/ServerPickerX.csproj b/ServerPickerX/ServerPickerX.csproj
index 62d2272..d4eabbb 100644
--- a/ServerPickerX/ServerPickerX.csproj
+++ b/ServerPickerX/ServerPickerX.csproj
@@ -6,6 +6,8 @@
true
true
+
+ true
partial
diff --git a/ServerPickerX/Services/SystemFirewalls/WindowsFirewallService.cs b/ServerPickerX/Services/SystemFirewalls/WindowsFirewallService.cs
index 433da09..a6bd377 100644
--- a/ServerPickerX/Services/SystemFirewalls/WindowsFirewallService.cs
+++ b/ServerPickerX/Services/SystemFirewalls/WindowsFirewallService.cs
@@ -20,73 +20,68 @@ public class WindowsFirewallService(
IProcessService _processService
) : ISystemFirewallService
{
- public async Task BlockServersAsync(ObservableCollection serverModels)
+ private const string FirewallPolicyProgId = "HNetCfg.FwPolicy2";
+ private const string FirewallRuleProgId = "HNetCfg.FWRule";
+ private const string FirewallRulePrefix = "server_picker_x_";
+ private const int FirewallRuleDirectionOutbound = 2;
+ private const int FirewallRuleActionBlock = 0;
+ private const int FirewallRuleProtocolAny = 256;
+ private const int FirewallRuleProfilesAll = int.MaxValue;
+
+ public Task BlockServersAsync(ObservableCollection serverModels)
{
- foreach (var serverModel in serverModels)
- {
- string ipAddresses = string.Join(",", serverModel.RelayModels.Select(s => s.IPv4).ToList());
-
- using var process = _processService.CreateProcess("cmd.exe");
-
- process.StartInfo.Arguments = $"/c {Path.Combine(Environment.SystemDirectory, "netsh.exe")} " +
- "advfirewall firewall " +
- "add rule " +
- "name=server_picker_x_" + serverModel.Description.Replace(" ", "") +
- " dir=out action=block protocol=ANY " + "remoteip=" + ipAddresses;
-
- try
- {
- process.Start();
- await process.WaitForExitAsync();
-
- string stdOut = process.StandardOutput.ReadToEnd().Trim();
- string stdErr = process.StandardError.ReadToEnd().Trim();
+ dynamic firewallRules = GetFirewallRules();
- if (process.ExitCode > 0)
- {
- await _loggerService.LogWarningAsync("StdOut: " + stdOut + " StdErr: " + stdErr);
- }
- }
- catch (Exception ex)
+ try
+ {
+ foreach (var serverModel in serverModels)
{
- // Perform debugging here if necessary (log error or through debugger breakpoints)
- throw;
+ string ruleName = GetFirewallRuleName(serverModel);
+ string ipAddresses = string.Join(",", serverModel.RelayModels.Select(s => s.IPv4).ToList());
+
+ RemoveFirewallRuleByName(firewallRules, ruleName);
+
+ dynamic firewallRule = CreateFirewallRule();
+ firewallRule.Name = ruleName;
+ firewallRule.Description = serverModel.Description;
+ firewallRule.Direction = FirewallRuleDirectionOutbound;
+ firewallRule.Action = FirewallRuleActionBlock;
+ firewallRule.Protocol = FirewallRuleProtocolAny;
+ firewallRule.RemoteAddresses = ipAddresses;
+ firewallRule.Enabled = true;
+ firewallRule.Profiles = FirewallRuleProfilesAll;
+
+ firewallRules.Add(firewallRule);
}
}
- }
-
- public async Task UnblockServersAsync(ObservableCollection serverModels)
- {
- foreach (var serverModel in serverModels)
+ catch (Exception)
{
- string ipAddresses = string.Join(",", serverModel.RelayModels.Select(s => s.IPv4).ToList());
-
- using var process = _processService.CreateProcess("cmd.exe");
-
- process.StartInfo.Arguments = $"/c {Path.Combine(Environment.SystemDirectory, "netsh.exe")} " +
- "advfirewall firewall " +
- "delete rule " +
- "name=server_picker_x_" + serverModel.Description.Replace(" ", "");
+ // Perform debugging here if necessary (log error or through debugger breakpoints)
+ throw;
+ }
- try
- {
- process.Start();
- await process.WaitForExitAsync();
+ return Task.CompletedTask;
+ }
- string stdOut = process.StandardOutput.ReadToEnd().Trim();
- string stdErr = process.StandardError.ReadToEnd().Trim();
+ public Task UnblockServersAsync(ObservableCollection serverModels)
+ {
+ dynamic firewallRules = GetFirewallRules();
- if (process.ExitCode > 0)
- {
- await _loggerService.LogWarningAsync("StdOut: " + stdOut + " StdErr: " + stdErr);
- }
- }
- catch (Exception ex)
+ try
+ {
+ foreach (var serverModel in serverModels)
{
- // Perform debugging here if necessary (log error or through debugger breakpoints)
- throw;
+ string ruleName = GetFirewallRuleName(serverModel);
+ RemoveFirewallRuleByName(firewallRules, ruleName);
}
}
+ catch (Exception)
+ {
+ // Perform debugging here if necessary (log error or through debugger breakpoints)
+ throw;
+ }
+
+ return Task.CompletedTask;
}
public async Task ResetFirewallAsync()
@@ -125,11 +120,60 @@ await _messageBoxService.ShowMessageBoxAsync(
MsBox.Avalonia.Enums.Icon.Success
);
}
- catch (Exception ex)
+ catch (Exception)
{
// Perform debugging here if necessary (log error or through debugger breakpoints)
throw;
}
}
+
+ private static dynamic CreateComObject(string progId)
+ {
+ Type? comType = Type.GetTypeFromProgID(progId);
+
+ if (comType == null)
+ {
+ throw new InvalidOperationException($"Unable to resolve COM ProgID '{progId}'.");
+ }
+
+ return Activator.CreateInstance(comType)
+ ?? throw new InvalidOperationException($"Unable to create COM instance for '{progId}'.");
+ }
+
+ private static dynamic GetFirewallRules()
+ {
+ dynamic firewallPolicy = CreateComObject(FirewallPolicyProgId);
+ return firewallPolicy.Rules;
+ }
+
+ private static dynamic CreateFirewallRule()
+ {
+ return CreateComObject(FirewallRuleProgId);
+ }
+
+ private static string GetFirewallRuleName(ServerModel serverModel)
+ {
+ return FirewallRulePrefix + serverModel.Description.Replace(" ", "");
+ }
+
+ private static void RemoveFirewallRuleByName(dynamic firewallRules, string ruleName)
+ {
+ while (TryGetFirewallRule(firewallRules, ruleName) != null)
+ {
+ firewallRules.Remove(ruleName);
+ }
+ }
+
+ private static dynamic? TryGetFirewallRule(dynamic firewallRules, string ruleName)
+ {
+ try
+ {
+ return firewallRules.Item(ruleName);
+ }
+ catch
+ {
+ return null;
+ }
+ }
}
-}
\ No newline at end of file
+}
From 2cba1aea50ca3e118ca2e02e1aac9a6156920084 Mon Sep 17 00:00:00 2001
From: JanitorialMess <65749353+JanitorialMess@users.noreply.github.com>
Date: Mon, 30 Mar 2026 15:22:53 -0400
Subject: [PATCH 2/6] refactor: rename firewall COM API helpers
---
.../SystemFirewalls/WindowsFirewallService.cs | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/ServerPickerX/Services/SystemFirewalls/WindowsFirewallService.cs b/ServerPickerX/Services/SystemFirewalls/WindowsFirewallService.cs
index a6bd377..8175342 100644
--- a/ServerPickerX/Services/SystemFirewalls/WindowsFirewallService.cs
+++ b/ServerPickerX/Services/SystemFirewalls/WindowsFirewallService.cs
@@ -30,7 +30,8 @@ IProcessService _processService
public Task BlockServersAsync(ObservableCollection serverModels)
{
- dynamic firewallRules = GetFirewallRules();
+ dynamic firewallPolicy = GetFirewallPolicyApi();
+ dynamic firewallRules = firewallPolicy.Rules;
try
{
@@ -41,7 +42,7 @@ public Task BlockServersAsync(ObservableCollection serverModels)
RemoveFirewallRuleByName(firewallRules, ruleName);
- dynamic firewallRule = CreateFirewallRule();
+ dynamic firewallRule = CreateFirewallRuleApi();
firewallRule.Name = ruleName;
firewallRule.Description = serverModel.Description;
firewallRule.Direction = FirewallRuleDirectionOutbound;
@@ -65,7 +66,8 @@ public Task BlockServersAsync(ObservableCollection serverModels)
public Task UnblockServersAsync(ObservableCollection serverModels)
{
- dynamic firewallRules = GetFirewallRules();
+ dynamic firewallPolicy = GetFirewallPolicyApi();
+ dynamic firewallRules = firewallPolicy.Rules;
try
{
@@ -140,13 +142,12 @@ private static dynamic CreateComObject(string progId)
?? throw new InvalidOperationException($"Unable to create COM instance for '{progId}'.");
}
- private static dynamic GetFirewallRules()
+ private static dynamic GetFirewallPolicyApi()
{
- dynamic firewallPolicy = CreateComObject(FirewallPolicyProgId);
- return firewallPolicy.Rules;
+ return CreateComObject(FirewallPolicyProgId);
}
- private static dynamic CreateFirewallRule()
+ private static dynamic CreateFirewallRuleApi()
{
return CreateComObject(FirewallRuleProgId);
}
From bf90a8baac69f64de23aae195e5235364548f768 Mon Sep 17 00:00:00 2001
From: FN-FAL113
Date: Tue, 31 Mar 2026 12:02:06 +0800
Subject: [PATCH 3/6] refactor: exception handling
---
.../SystemFirewalls/WindowsFirewallService.cs | 29 +++++++++----------
1 file changed, 14 insertions(+), 15 deletions(-)
diff --git a/ServerPickerX/Services/SystemFirewalls/WindowsFirewallService.cs b/ServerPickerX/Services/SystemFirewalls/WindowsFirewallService.cs
index 8175342..64f331e 100644
--- a/ServerPickerX/Services/SystemFirewalls/WindowsFirewallService.cs
+++ b/ServerPickerX/Services/SystemFirewalls/WindowsFirewallService.cs
@@ -28,13 +28,13 @@ IProcessService _processService
private const int FirewallRuleProtocolAny = 256;
private const int FirewallRuleProfilesAll = int.MaxValue;
- public Task BlockServersAsync(ObservableCollection serverModels)
+ public async Task BlockServersAsync(ObservableCollection serverModels)
{
- dynamic firewallPolicy = GetFirewallPolicyApi();
- dynamic firewallRules = firewallPolicy.Rules;
-
try
{
+ dynamic firewallPolicy = GetFirewallPolicyApi();
+ dynamic firewallRules = firewallPolicy.Rules;
+
foreach (var serverModel in serverModels)
{
string ruleName = GetFirewallRuleName(serverModel);
@@ -55,35 +55,33 @@ public Task BlockServersAsync(ObservableCollection serverModels)
firewallRules.Add(firewallRule);
}
}
- catch (Exception)
+ catch (Exception ex)
{
// Perform debugging here if necessary (log error or through debugger breakpoints)
+ await _loggerService.LogErrorAsync(ex.Message);
throw;
}
-
- return Task.CompletedTask;
}
- public Task UnblockServersAsync(ObservableCollection serverModels)
+ public async Task UnblockServersAsync(ObservableCollection serverModels)
{
- dynamic firewallPolicy = GetFirewallPolicyApi();
- dynamic firewallRules = firewallPolicy.Rules;
-
try
{
+ dynamic firewallPolicy = GetFirewallPolicyApi();
+ dynamic firewallRules = firewallPolicy.Rules;
+
foreach (var serverModel in serverModels)
{
string ruleName = GetFirewallRuleName(serverModel);
RemoveFirewallRuleByName(firewallRules, ruleName);
}
}
- catch (Exception)
+ catch (Exception ex)
{
// Perform debugging here if necessary (log error or through debugger breakpoints)
+ await _loggerService.LogErrorAsync(ex.Message);
throw;
}
-
- return Task.CompletedTask;
}
public async Task ResetFirewallAsync()
@@ -122,9 +120,10 @@ await _messageBoxService.ShowMessageBoxAsync(
MsBox.Avalonia.Enums.Icon.Success
);
}
- catch (Exception)
+ catch (Exception ex)
{
// Perform debugging here if necessary (log error or through debugger breakpoints)
+ await _loggerService.LogErrorAsync(ex.Message);
throw;
}
}
From e6ce51deb838d3f5a7e65e41e125406c41e0215c Mon Sep 17 00:00:00 2001
From: FN-FAL113
Date: Tue, 31 Mar 2026 12:27:38 +0800
Subject: [PATCH 4/6] chore: bump assembly version
---
ServerPickerX/ServerPickerX.csproj | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/ServerPickerX/ServerPickerX.csproj b/ServerPickerX/ServerPickerX.csproj
index d4eabbb..2d55f8c 100644
--- a/ServerPickerX/ServerPickerX.csproj
+++ b/ServerPickerX/ServerPickerX.csproj
@@ -22,8 +22,8 @@
https://github.com/FN-FAL113/server-picker-x
https://github.com/FN-FAL113/server-picker-x
Assets\favicon.ico
- 1.0.3.0
- 1.0.3.0
+ 1.0.4.0
+ 1.0.4.0
From 5f6f919d0dc2828e6916f64446ae3235fe4e49a1 Mon Sep 17 00:00:00 2001
From: FN-FAL113
Date: Tue, 31 Mar 2026 14:50:50 +0800
Subject: [PATCH 5/6] refactor: use Interop.NetFwTypeLib.dll assembly for
static types
---
ServerPickerX/ServerPickerX.csproj | 4 +
.../SystemFirewalls/WindowsFirewallService.cs | 70 +++++-------------
ServerPickerX/libs/Interop.NetFwTypeLib.dll | Bin 0 -> 22016 bytes
3 files changed, 23 insertions(+), 51 deletions(-)
create mode 100644 ServerPickerX/libs/Interop.NetFwTypeLib.dll
diff --git a/ServerPickerX/ServerPickerX.csproj b/ServerPickerX/ServerPickerX.csproj
index 2d55f8c..64d084c 100644
--- a/ServerPickerX/ServerPickerX.csproj
+++ b/ServerPickerX/ServerPickerX.csproj
@@ -33,6 +33,10 @@
+
+ libs\Interop.NetFwTypeLib.dll
+ true
+
diff --git a/ServerPickerX/Services/SystemFirewalls/WindowsFirewallService.cs b/ServerPickerX/Services/SystemFirewalls/WindowsFirewallService.cs
index 64f331e..998acfc 100644
--- a/ServerPickerX/Services/SystemFirewalls/WindowsFirewallService.cs
+++ b/ServerPickerX/Services/SystemFirewalls/WindowsFirewallService.cs
@@ -10,6 +10,7 @@
using System.IO;
using System.Linq;
using System.Threading.Tasks;
+using NetFwTypeLib;
namespace ServerPickerX.Services.SystemFirewalls
{
@@ -20,11 +21,9 @@ public class WindowsFirewallService(
IProcessService _processService
) : ISystemFirewallService
{
- private const string FirewallPolicyProgId = "HNetCfg.FwPolicy2";
- private const string FirewallRuleProgId = "HNetCfg.FWRule";
private const string FirewallRulePrefix = "server_picker_x_";
- private const int FirewallRuleDirectionOutbound = 2;
- private const int FirewallRuleActionBlock = 0;
+ private const NET_FW_RULE_DIRECTION_ FirewallRuleDirectionOutbound = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_OUT;
+ private const NET_FW_ACTION_ FirewallRuleActionBlock = NET_FW_ACTION_.NET_FW_ACTION_BLOCK;
private const int FirewallRuleProtocolAny = 256;
private const int FirewallRuleProfilesAll = int.MaxValue;
@@ -32,17 +31,17 @@ public async Task BlockServersAsync(ObservableCollection serverMode
{
try
{
- dynamic firewallPolicy = GetFirewallPolicyApi();
- dynamic firewallRules = firewallPolicy.Rules;
+ INetFwPolicy2 firewallPolicy = GetFirewallPolicyApi();
+ INetFwRules firewallRules = firewallPolicy.Rules;
foreach (var serverModel in serverModels)
{
string ruleName = GetFirewallRuleName(serverModel);
- string ipAddresses = string.Join(",", serverModel.RelayModels.Select(s => s.IPv4).ToList());
+ string ipAddresses = string.Join(",", serverModel.RelayModels.Select(s => s.IPv4));
RemoveFirewallRuleByName(firewallRules, ruleName);
- dynamic firewallRule = CreateFirewallRuleApi();
+ INetFwRule firewallRule = CreateFirewallRuleApi();
firewallRule.Name = ruleName;
firewallRule.Description = serverModel.Description;
firewallRule.Direction = FirewallRuleDirectionOutbound;
@@ -57,7 +56,6 @@ public async Task BlockServersAsync(ObservableCollection serverMode
}
catch (Exception ex)
{
- // Perform debugging here if necessary (log error or through debugger breakpoints)
await _loggerService.LogErrorAsync(ex.Message);
throw;
}
@@ -67,8 +65,8 @@ public async Task UnblockServersAsync(ObservableCollection serverMo
{
try
{
- dynamic firewallPolicy = GetFirewallPolicyApi();
- dynamic firewallRules = firewallPolicy.Rules;
+ INetFwPolicy2 firewallPolicy = GetFirewallPolicyApi();
+ INetFwRules firewallRules = firewallPolicy.Rules;
foreach (var serverModel in serverModels)
{
@@ -78,7 +76,6 @@ public async Task UnblockServersAsync(ObservableCollection serverMo
}
catch (Exception ex)
{
- // Perform debugging here if necessary (log error or through debugger breakpoints)
await _loggerService.LogErrorAsync(ex.Message);
throw;
}
@@ -92,10 +89,7 @@ public async Task ResetFirewallAsync()
MsBox.Avalonia.Enums.Icon.Warning
);
- if (!result)
- {
- return;
- }
+ if (!result) return;
using Process process = _processService.CreateProcess("cmd.exe");
@@ -122,41 +116,21 @@ await _messageBoxService.ShowMessageBoxAsync(
}
catch (Exception ex)
{
- // Perform debugging here if necessary (log error or through debugger breakpoints)
await _loggerService.LogErrorAsync(ex.Message);
throw;
}
}
- private static dynamic CreateComObject(string progId)
- {
- Type? comType = Type.GetTypeFromProgID(progId);
-
- if (comType == null)
- {
- throw new InvalidOperationException($"Unable to resolve COM ProgID '{progId}'.");
- }
-
- return Activator.CreateInstance(comType)
- ?? throw new InvalidOperationException($"Unable to create COM instance for '{progId}'.");
- }
-
- private static dynamic GetFirewallPolicyApi()
- {
- return CreateComObject(FirewallPolicyProgId);
- }
+ private static INetFwPolicy2 GetFirewallPolicyApi()
+ => (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("E2B3C97F-6AE1-41AC-817A-F6F92166D7DD"))!)!;
- private static dynamic CreateFirewallRuleApi()
- {
- return CreateComObject(FirewallRuleProgId);
- }
+ private static INetFwRule CreateFirewallRuleApi()
+ => (INetFwRule)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("2C5BC43E-3369-4C33-AB0C-BE9469677AF4"))!)!;
private static string GetFirewallRuleName(ServerModel serverModel)
- {
- return FirewallRulePrefix + serverModel.Description.Replace(" ", "");
- }
+ => FirewallRulePrefix + serverModel.Description.Replace(" ", "");
- private static void RemoveFirewallRuleByName(dynamic firewallRules, string ruleName)
+ private static void RemoveFirewallRuleByName(INetFwRules firewallRules, string ruleName)
{
while (TryGetFirewallRule(firewallRules, ruleName) != null)
{
@@ -164,16 +138,10 @@ private static void RemoveFirewallRuleByName(dynamic firewallRules, string ruleN
}
}
- private static dynamic? TryGetFirewallRule(dynamic firewallRules, string ruleName)
+ private static INetFwRule? TryGetFirewallRule(INetFwRules firewallRules, string ruleName)
{
- try
- {
- return firewallRules.Item(ruleName);
- }
- catch
- {
- return null;
- }
+ try { return firewallRules.Item(ruleName); }
+ catch { return null; }
}
}
}
diff --git a/ServerPickerX/libs/Interop.NetFwTypeLib.dll b/ServerPickerX/libs/Interop.NetFwTypeLib.dll
new file mode 100644
index 0000000000000000000000000000000000000000..d52e0edf2b7f1ba61c599597e5d0ebe68b494e9c
GIT binary patch
literal 22016
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
Date: Tue, 31 Mar 2026 15:19:24 +0800
Subject: [PATCH 6/6] chore: private property naming convention
---
.../SystemFirewalls/WindowsFirewallService.cs | 38 ++++++++++---------
1 file changed, 21 insertions(+), 17 deletions(-)
diff --git a/ServerPickerX/Services/SystemFirewalls/WindowsFirewallService.cs b/ServerPickerX/Services/SystemFirewalls/WindowsFirewallService.cs
index 998acfc..4684002 100644
--- a/ServerPickerX/Services/SystemFirewalls/WindowsFirewallService.cs
+++ b/ServerPickerX/Services/SystemFirewalls/WindowsFirewallService.cs
@@ -21,11 +21,11 @@ public class WindowsFirewallService(
IProcessService _processService
) : ISystemFirewallService
{
- private const string FirewallRulePrefix = "server_picker_x_";
- private const NET_FW_RULE_DIRECTION_ FirewallRuleDirectionOutbound = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_OUT;
- private const NET_FW_ACTION_ FirewallRuleActionBlock = NET_FW_ACTION_.NET_FW_ACTION_BLOCK;
- private const int FirewallRuleProtocolAny = 256;
- private const int FirewallRuleProfilesAll = int.MaxValue;
+ private const string _firewallRulePrefix = "server_picker_x_";
+ private const NET_FW_RULE_DIRECTION_ _firewallRuleDirectionOutbound = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_OUT;
+ private const NET_FW_ACTION_ _firewallRuleActionBlock = NET_FW_ACTION_.NET_FW_ACTION_BLOCK;
+ private const int _firewallRuleProtocolAny = 256;
+ private const int _firewallRuleProfilesAll = int.MaxValue;
public async Task BlockServersAsync(ObservableCollection serverModels)
{
@@ -44,12 +44,12 @@ public async Task BlockServersAsync(ObservableCollection serverMode
INetFwRule firewallRule = CreateFirewallRuleApi();
firewallRule.Name = ruleName;
firewallRule.Description = serverModel.Description;
- firewallRule.Direction = FirewallRuleDirectionOutbound;
- firewallRule.Action = FirewallRuleActionBlock;
- firewallRule.Protocol = FirewallRuleProtocolAny;
+ firewallRule.Direction = _firewallRuleDirectionOutbound;
+ firewallRule.Action = _firewallRuleActionBlock;
+ firewallRule.Protocol = _firewallRuleProtocolAny;
firewallRule.RemoteAddresses = ipAddresses;
firewallRule.Enabled = true;
- firewallRule.Profiles = FirewallRuleProfilesAll;
+ firewallRule.Profiles = _firewallRuleProfilesAll;
firewallRules.Add(firewallRule);
}
@@ -121,16 +121,16 @@ await _messageBoxService.ShowMessageBoxAsync(
}
}
- private static INetFwPolicy2 GetFirewallPolicyApi()
+ public INetFwPolicy2 GetFirewallPolicyApi()
=> (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("E2B3C97F-6AE1-41AC-817A-F6F92166D7DD"))!)!;
- private static INetFwRule CreateFirewallRuleApi()
+ public INetFwRule CreateFirewallRuleApi()
=> (INetFwRule)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("2C5BC43E-3369-4C33-AB0C-BE9469677AF4"))!)!;
- private static string GetFirewallRuleName(ServerModel serverModel)
- => FirewallRulePrefix + serverModel.Description.Replace(" ", "");
+ public string GetFirewallRuleName(ServerModel serverModel)
+ => _firewallRulePrefix + serverModel.Description.Replace(" ", "");
- private static void RemoveFirewallRuleByName(INetFwRules firewallRules, string ruleName)
+ public void RemoveFirewallRuleByName(INetFwRules firewallRules, string ruleName)
{
while (TryGetFirewallRule(firewallRules, ruleName) != null)
{
@@ -138,10 +138,14 @@ private static void RemoveFirewallRuleByName(INetFwRules firewallRules, string r
}
}
- private static INetFwRule? TryGetFirewallRule(INetFwRules firewallRules, string ruleName)
+ public INetFwRule? TryGetFirewallRule(INetFwRules firewallRules, string ruleName)
{
- try { return firewallRules.Item(ruleName); }
- catch { return null; }
+ try
+ {
+ return firewallRules.Item(ruleName);
+ } catch {
+ return null;
+ }
}
}
}