一点背景:基本上我想向私有和公共网络添加程序防火墙访问规则。
我以前用过这个- “netsh 防火墙添加 allowedprogram 程序=“路径..”名称=应用程序名称启用范围=所有配置文件=当前”
但现在我想使用 COM 对象稍微自动化一下该过程。 找到了这段闪亮的代码 - http://web.archive.org/web/20070707110141/http://www.dot.net.nz/Default.aspx?tabid=42&mid=404&ctl=Details&ItemID=8
在实现了我一直尝试使用的课程之后- FirewallHelper.Instance.GrantAuthorization(@"路径...","应用程序名称",NET_FW_SCOPE_.NET_FW_SCOPE_ALL,NET_FW_IP_VERSION_.NET_FW_IP_VERSION_ANY);
我面临的问题是 GrantAuthorization 方法只会为公共或专用网络添加一条规则,而我的旧 netsh 命令将为每个网络添加 2 条规则 - 1 条。
这些命令实际上看起来非常相似,所以对我来说有点令人困惑。
那么...如何添加两个网络规则?
肖恩
我的答案来自大卫的回答,但更详细。并修复有关设置本地端口的问题。在设置本地端口之前,您需要先设置协议。更多详情如下:
首先,需要导入引用FirewallAPI.dll。它位于“C:\Windows\System32\FirewallAPI.dll”中 然后:
using NetFwTypeLib;
并将代码插入您的:
Type tNetFwPolicy2 = Type.GetTypeFromProgID("HNetCfg.FwPolicy2");
INetFwPolicy2 fwPolicy2 = (INetFwPolicy2)Activator.CreateInstance(tNetFwPolicy2);
var currentProfiles = fwPolicy2.CurrentProfileTypes;
// Let's create a new rule
INetFwRule2 inboundRule = (INetFwRule2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FWRule"));
inboundRule.Enabled = true;
//Allow through firewall
inboundRule.Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW;
//Using protocol TCP
inboundRule.Protocol = 6; // TCP
//Port 81
inboundRule.LocalPorts = "81";
//Name of rule
inboundRule.Name = "MyRule";
// ...//
inboundRule.Profiles = currentProfiles;
// Now add the rule
INetFwPolicy2 firewallPolicy = (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2"));
firewallPolicy.Rules.Add(inboundRule);
我认为您最好的选择是与具有高级安全 API 的 Windows 防火墙交谈。
快速谷歌搜索“C# INetFwRule2”将向您展示大量有关如何注册或更新防火墙规则的示例。
为了增加公共和私人政策,我使用了类似的东西
Type tNetFwPolicy2 = Type.GetTypeFromProgID("HNetCfg.FwPolicy2");
INetFwPolicy2 fwPolicy2 = (INetFwPolicy2)Activator.CreateInstance(tNetFwPolicy2);
var currentProfiles = fwPolicy2.CurrentProfileTypes;
// Let's create a new rule
INetFwRule2 inboundRule = (INetFwRule2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FWRule"));
inboundRule.Enabled = true;
inboundRule.LocalPorts = "1234";
inboundRule.Protocol = 6; // TCP
// ...
inboundRule.Profiles = currentProfiles;
// Now add the rule
INetFwPolicy2 firewallPolicy = (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2"));
firewallPolicy.Rules.Add(inboundRule);
此页面并没有说这个问题已经得到回答并且已经过时了,所以为了以防万一,为了将来的使用,我会回答这个问题。
首先导入引用FirewallAPI.dll,位于“C:\Windows\System32\FirewallAPI.dll”,然后添加using指令
using NetFwTypeLib;
inboundRule.Profiles
属性似乎被分类为一组具有以下值的标志(该属性的类型是 int,所以我做了一个枚举):
public enum FirewallProfiles
{
Domain = 1,
Private = 2,
Public = 4
}
因此,使用该代码,我们可以将配置文件更改为以下内容:
// Create a new rule
INetFwRule2 inboundRule = (INetFwRule2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwRule"));
// Enable the rule
inboundRule.Enabled = true;
// Allow through firewall
inboundRule.Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW;
// Using protocol TCP
inboundRule.Protocol = 6; // TCP
// Set port number
inboundRule.LocalPorts = "1234";
// Name of rule
inboundRule.Name = "Name Of Firewall Rule";
// Set profiles
inboundRule.Profiles = (int)(FirewallProfiles.Private | FirewallProfiles.Public);
// Add the rule
INetFwPolicy2 firewallPolicy = (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2"));
firewallPolicy.Rules.Add(inboundRule);
或者您可以将
inboundRule.Profiles
更改为 int 值。
两个注意事项:
1:如果您不在管理权限下运行此代码,
firewallPolicty.Rules.Add(inboundRule);
会抛出异常。
2:
inboundRule.Profiles
必须在值1到7之间。否则会抛出异常
以防万一你们想要出站规则:
inboundRule.Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_OUT;
我们可以使用
netsh
命令来执行此操作,使用标准 Process
来运行 cmd.exe
。 netsh
命令首先检查防火墙规则是否存在,如果不存在则创建它。
static void SetFirewallException(string ruleName, string exePath)
{
// Checks for the rule by name and creates it if it doesn't exist.
string script = $@"netsh advfirewall firewall show rule name=""{ruleName}"" > nul & if errorlevel 1 (netsh advfirewall firewall add rule name=""{ruleName}"" dir=in action=allow program=""{exePath}"" enable=yes)";
Process process = new Process();
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.Arguments = "/c " + script;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.Start();
process.WaitForExit();
}