使用自动化Windows防火墙

时间:2012-01-17 04:18:05

标签: c# windows-7 com port firewall

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

当我运行程序时,我得到如下错误:“灾难性故障(HRESULT异常: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);
    }
}

3 个答案:

答案 0 :(得分:10)

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();
    
  3. / *使用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;
            }
        }
    
      } 
    }
    

答案 1 :(得分:4)

Javanese Girl接受的答案具有类似C的实现,具有无声明使用模式和冗余代码。这是基于该答案的重构实现。它使用所有相同的调用FirewallAPI.dll;它在功能上是等价的,因此它解决了原始问题的问题,即无法使这些类型的防火墙操作起作用。此解决方案有一个简单的界面,隐藏所有细节: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;
    }
}

答案 2 :(得分:1)

我是通过Google来到这里的,目的是寻找一种列出Windows防火墙开放端口的.net方法。上述答案无效。具体来说,firewall.LocalPolicy.CurrentProfile.GloballyOpenPorts的计数始终为零。这些答案很旧,很可能适用于Windows7。此代码在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");
                }
            }
        }
    }
}

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