【问题标题】:Automating Windows Firewall with自动化 Windows 防火墙
【发布时间】:2025-12-04 13:50:01
【问题描述】:

我有 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);
    }
}

【问题讨论】:

  • 是否存在“内部错误”(内部异常)?

标签: c# windows-7 com port firewall


【解决方案1】:

我通过 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");
                }
            }
        }
    }
}

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

【讨论】:

    【解决方案2】:

    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;
        }
    }
    

    【讨论】:

      【解决方案3】:

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

      1. 在使用以下程序之前,请将参考 FirewallAPI.dll 添加到 Visual Studio 2010。 请执行下列操作: Visual Studio 2010Solution Explorer右键单击项目 - 选择 Add Reference - 选择 C:\Windows\System32\FirewallAPI.dll - 好的

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

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

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

      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;
              }
          }
      
        } 
      }
      

      【讨论】: