使用自动化Windows防火墙

我有C#应用程序使用PORT 777进行异步通信,PORT 3306用于与My Sql Server进行通信。 端口被防火墙阻止时出现问题。 我试图创建一个程序,在Windows 7的防火墙列表中添加一个例外。

当我运行程序时,我得到如下错误:“灾难性故障(HRESULTexception:0x8000FFFF(E_UNEXPECTED))”。

我不明白这些错误是什么意思,欢迎提出任何建议,谢谢。

protected internal void AddExceptionToFirewall(){ try { INetFwMgr fireWall = null; INetFwAuthorizedApplications apps = null; INetFwAuthorizedApplication app = null; Type progID = null; INetFwOpenPorts ports = null; INetFwOpenPort asyncPort = null; INetFwOpenPort mysqlPort = null; bool appFounded = false; bool asyncPortFounded = false; bool mysqlPortFounded = false; progID = Type.GetTypeFromProgID("HNetCfg.FwMgr"); // checking for Windows Firewall fireWall = (INetFwMgr)Activator.CreateInstance(progID); if (fireWall.LocalPolicy.CurrentProfile.FirewallEnabled) { // obtain the list of authorized applications apps = (INetFwAuthorizedApplications)fireWall.LocalPolicy.CurrentProfile.AuthorizedApplications; IEnumerator appEnumerate = apps.GetEnumerator(); while (appEnumerate.MoveNext()){ app = (INetFwAuthorizedApplication)appEnumerate.Current; if (app.Name == Application.ProductName){ appFounded = true; break; } } // add this application to the list of authorized applications if(appFounded==false){ app.Name = Application.ProductName; StringBuilder strBuild = new StringBuilder(); strBuild.Append(Application.ExecutablePath.Replace("\\","\\\\")); app.ProcessImageFileName = strBuild.ToString(); app.Enabled = true; apps = (INetFwAuthorizedApplications)fireWall.LocalPolicy.CurrentProfile.AuthorizedApplications; apps.Add(app); } // obtain the list of authorized asynchronous socket ports (777) ports = (INetFwOpenPorts)fireWall.LocalPolicy.CurrentProfile.GloballyOpenPorts; IEnumerator portEnumerate = ports.GetEnumerator(); while (portEnumerate.MoveNext()) { asyncPort = (INetFwOpenPort)portEnumerate.Current; if (asyncPort.Port == 777) { asyncPortFounded = true; break; } } // add a port 777 to globally open ports if (asyncPortFounded==false) ports.Add(asyncPort); // obtain the list of authorized mysql socket ports(3306) while (portEnumerate.MoveNext()) { mysqlPort = (INetFwOpenPort)portEnumerate.Current; if (mysqlPort.Port == 3306) { mysqlPortFounded = true; break; } } // add a port 3306 to globally open ports if (mysqlPortFounded == false) ports.Add(mysqlPort); } } catch (COMException cm) { MessageBox.Show(cm.Message); } catch (Exception ex) { MessageBox.Show(ex.Message); } } 

http://www.codeproject.com/Articles/14906/Open-Windows-Firewall-During-Installation

  1. 在使用下面的程序之前,请将参考FirewallAPI.dll添加到Visual Studio 2010.执行以下操作:从Visual Studio 2010解决方案资源管理器右键单击项目 – 选择添加引用 – 选择C:\ Windows \ System32 \ FirewallAPI。 dll – 好的

  2. 使用以下3行代码调用程序防火墙。 您可以将此代码放在程序的表单加载中:

      private clsFirewall objFirewall = new clsFirewall(); objFirewall.CloseFirewall(); objFirewall.OpenFirewall(); 

/ *使用C#自动化Windows防火墙支持Windows 7 * /

 using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Diagnostics; using System.Threading; using NetFwTypeLib; using System.Windows.Forms; namespace MyFirewall { public class clsFirewall { private int[] portsSocket = { 777, 3306 }; private string[] portsName = { "AsyncPort", "MySqlPort" }; private INetFwProfile fwProfile = null; protected internal void OpenFirewall() { INetFwAuthorizedApplications authApps = null; INetFwAuthorizedApplication authApp = null; INetFwOpenPorts openPorts = null; INetFwOpenPort openPort = null; try { if (isAppFound(Application.ProductName + " Server") == false) { SetProfile(); authApps = fwProfile.AuthorizedApplications; authApp = GetInstance("INetAuthApp") as INetFwAuthorizedApplication; authApp.Name = Application.ProductName + " Server"; authApp.ProcessImageFileName = Application.ExecutablePath; authApps.Add(authApp); } if (isPortFound(portsSocket[0]) == false) { SetProfile(); openPorts = fwProfile.GloballyOpenPorts; openPort = GetInstance("INetOpenPort") as INetFwOpenPort; openPort.Port = portsSocket[0]; openPort.Protocol = NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_TCP; openPort.Name = portsName[0]; openPorts.Add(openPort); } if (isPortFound(portsSocket[1]) == false) { SetProfile(); openPorts = fwProfile.GloballyOpenPorts; openPort = GetInstance("INetOpenPort") as INetFwOpenPort; openPort.Port = portsSocket[1]; openPort.Protocol = NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_TCP; openPort.Name = portsName[1]; openPorts.Add(openPort); } } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { if (authApps != null) authApps = null; if (authApp != null) authApp = null; if (openPorts != null) openPorts = null; if (openPort != null) openPort = null; } } protected internal void CloseFirewall() { INetFwAuthorizedApplications apps = null; INetFwOpenPorts ports = null; try { if (isAppFound(Application.ProductName + " Server") == true) { SetProfile(); apps = fwProfile.AuthorizedApplications; apps.Remove(Application.ExecutablePath); } if (isPortFound(portsSocket[0]) == true) { SetProfile(); ports = fwProfile.GloballyOpenPorts; ports.Remove(portsSocket[0], NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_TCP); } if (isPortFound(portsSocket[1]) == true) { SetProfile(); ports = fwProfile.GloballyOpenPorts; ports.Remove(portsSocket[1], NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_TCP); } } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { if (apps != null) apps = null; if (ports != null) ports = null; } } protected internal bool isAppFound(string appName) { bool boolResult = false; Type progID = null; INetFwMgr firewall = null; INetFwAuthorizedApplications apps = null; INetFwAuthorizedApplication app = null; try { progID = Type.GetTypeFromProgID("HNetCfg.FwMgr"); firewall = Activator.CreateInstance(progID) as INetFwMgr; if (firewall.LocalPolicy.CurrentProfile.FirewallEnabled) { apps = firewall.LocalPolicy.CurrentProfile.AuthorizedApplications; IEnumerator appEnumerate = apps.GetEnumerator(); while ((appEnumerate.MoveNext())) { app = appEnumerate.Current as INetFwAuthorizedApplication; if (app.Name == appName) { boolResult = true; break; } } } } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { if (progID != null) progID = null; if (firewall != null) firewall = null; if (apps != null) apps = null; if (app != null) app = null; } return boolResult; } protected internal bool isPortFound(int portNumber) { bool boolResult = false; INetFwOpenPorts ports = null; Type progID = null; INetFwMgr firewall = null; INetFwOpenPort currentPort = null; try { progID = Type.GetTypeFromProgID("HNetCfg.FwMgr"); firewall = Activator.CreateInstance(progID) as INetFwMgr; ports = firewall.LocalPolicy.CurrentProfile.GloballyOpenPorts; IEnumerator portEnumerate = ports.GetEnumerator(); while ((portEnumerate.MoveNext())) { currentPort = portEnumerate.Current as INetFwOpenPort; if (currentPort.Port == portNumber) { boolResult = true; break; } } } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { if (ports != null) ports = null; if (progID != null) progID = null; if (firewall != null) firewall = null; if (currentPort != null) currentPort = null; } return boolResult; } protected internal void SetProfile() { INetFwMgr fwMgr = null; INetFwPolicy fwPolicy = null; try { fwMgr = GetInstance("INetFwMgr") as INetFwMgr; fwPolicy = fwMgr.LocalPolicy; fwProfile = fwPolicy.CurrentProfile; } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { if (fwMgr != null) fwMgr = null; if (fwPolicy != null) fwPolicy = null; } } protected internal object GetInstance(string typeName) { Type tpResult = null; switch (typeName) { case "INetFwMgr": tpResult = Type.GetTypeFromCLSID(new Guid("{304CE942-6E39-40D8-943A-B913C40C9CD4}")); return Activator.CreateInstance(tpResult); case "INetAuthApp": tpResult = Type.GetTypeFromCLSID(new Guid("{EC9846B3-2762-4A6B-A214-6ACB603462D2}")); return Activator.CreateInstance(tpResult); case "INetOpenPort": tpResult = Type.GetTypeFromCLSID(new Guid("{0CA545C6-37AD-4A6C-BF92-9F7610067EF5}")); return Activator.CreateInstance(tpResult); default: return null; } } } } 

Javanese Girl接受的答案有一个类似C的实现,具有无声明使用模式和冗余代码。 这是基于该答案的重构实现。 它使用所有相同的调用进入FirewallAPI.dll; 它在function上是等价的,因此它解决了原始问题无法使这些类型的防火墙操作起作用的问题。 此解决方案具有隐藏所有详细信息的简单界面:IsPortOpen,OpenPort和ClosePort。

用法示例:

 int port = 9914; if (IsPortOpen(port)) ClosePort(port); OpenPort(port, "StreamBeam API"); 

执行:

 using System; using System.Collections; using NetFwTypeLib; namespace YourCompany { public static class FirewallUtils { public static bool IsPortOpen(int port) { EnsureSetup(); Type progID = Type.GetTypeFromProgID("HNetCfg.FwMgr"); INetFwMgr firewall = Activator.CreateInstance(progID) as INetFwMgr; INetFwOpenPorts ports = firewall.LocalPolicy.CurrentProfile.GloballyOpenPorts; IEnumerator portEnumerate = ports.GetEnumerator(); while ((portEnumerate.MoveNext())) { INetFwOpenPort currentPort = portEnumerate.Current as INetFwOpenPort; if (currentPort.Port == port) return true; } return false; } public static void OpenPort(int port, string applicationName) { EnsureSetup(); if (IsPortOpen(port)) return; INetFwOpenPort openPort = GetInstance("INetOpenPort") as INetFwOpenPort; openPort.Port = port; openPort.Protocol = NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_TCP; openPort.Name = applicationName; INetFwOpenPorts openPorts = sm_fwProfile.GloballyOpenPorts; openPorts.Add(openPort); } public static void ClosePort(int port) { EnsureSetup(); if (!IsPortOpen(port)) return; INetFwOpenPorts ports = sm_fwProfile.GloballyOpenPorts; ports.Remove(port, NET_FW_IP_PROTOCOL_.NET_FW_IP_PROTOCOL_TCP); } private static object GetInstance(string typeName) { Type tpResult = null; switch (typeName) { case "INetFwMgr": tpResult = Type.GetTypeFromCLSID(new Guid("{304CE942-6E39-40D8-943A-B913C40C9CD4}")); return Activator.CreateInstance(tpResult); case "INetAuthApp": tpResult = Type.GetTypeFromCLSID(new Guid("{EC9846B3-2762-4A6B-A214-6ACB603462D2}")); return Activator.CreateInstance(tpResult); case "INetOpenPort": tpResult = Type.GetTypeFromCLSID(new Guid("{0CA545C6-37AD-4A6C-BF92-9F7610067EF5}")); return Activator.CreateInstance(tpResult); default: throw new Exception("Unknown type name: " + typeName); } } private static void EnsureSetup() { if (sm_fwProfile != null) return; INetFwMgr fwMgr = GetInstance("INetFwMgr") as INetFwMgr; sm_fwProfile = fwMgr.LocalPolicy.CurrentProfile; } private static INetFwProfile sm_fwProfile = null; } } 

我是通过Google来到这里寻找一种列出Windows防火墙开放端口的.net方法。 上述答案无效。 具体来说,firewall.LocalPolicy.CurrentProfile.GloballyOpenPorts的计数始终为零。 这些答案很老,可能适用于Windows 7.在Windows 10上对我有用的是这段代码。

 using System; using System.Collections; using NetFwTypeLib; namespace FirewallPorts { class FwPorts { static void Main(string[] args) { Type fwPolicy2Type = Type.GetTypeFromProgID("HNetCfg.FwPolicy2", true); INetFwPolicy2 fwPolicy = (INetFwPolicy2)Activator.CreateInstance(fwPolicy2Type); int currentProfs = fwPolicy.CurrentProfileTypes; NET_FW_PROFILE_TYPE2_ foo = (NET_FW_PROFILE_TYPE2_)currentProfs; if (foo.HasFlag(NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_PRIVATE)) Console.WriteLine("PrivateNet"); if (!foo.HasFlag(NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_PUBLIC)) Console.WriteLine("NOT PUBLIC"); bool fpsEnabled = fwPolicy.IsRuleGroupCurrentlyEnabled["File and Printer Sharing"]; bool FwEnabled = fwPolicy.FirewallEnabled[NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_PUBLIC] || fwPolicy.FirewallEnabled[NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_PRIVATE]; Console.WriteLine($"Windows Firewall enabled is {FwEnabled}"); INetFwRules rules = fwPolicy.Rules; foreach (INetFwRule item in rules) { if (item.Enabled && item.Name.Contains("Sharing")) { Console.WriteLine(item.Name); Console.WriteLine($"LocalPorts: {item.LocalPorts}, {(NET_FW_PROFILE_TYPE2_)item.Profiles}"); Console.WriteLine(item.Description + "\r\n"); } } } } } 

我不需要打开或关闭端口,但可以通过更改规则状态或创建新规则并启用它们来完成。 希望这可以节省其他人几个小时。