You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取Windows防火墙出站规则名称列表?Delphi代码报错求助

解决Delphi获取防火墙出站规则名称时的"系统找不到指定文件"错误

问题根源

  • 直接使用OleVariant访问旧版HNetCfg.FwPolicy2 COM对象,在Win10/Win11等新系统上存在兼容性问题,容易触发文件找不到的错误。
  • 原代码使用CoInitialize(nil)初始化COM,默认线程模型可能与防火墙API要求的单线程公寓模型不匹配,导致访问失败。
  • 未检查COM对象/集合的有效性,直接访问引发异常。

解决方案

方案1:修复现有OleVariant代码

调整COM初始化方式,增加对象有效性检查,使用常量替代魔法数字:

const
  NET_FW_RULE_DIR_OUT = 2; // 出站规则方向常量

function GetOutboundFirewallRuleNames: TStringList;
var
  i: Integer;
  fwPolicy2: OleVariant;
  rule: OleVariant;
begin
  Result := TStringList.Create;
  try
    // 使用单线程公寓模型初始化COM,匹配防火墙API要求
    if CoInitializeEx(nil, COINIT_APARTMENTTHREADED) <> S_OK then
      raise Exception.Create('COM初始化失败');
    try
      fwPolicy2 := CreateOleObject('HNetCfg.FwPolicy2');
      
      // 先验证Rules集合是否有效
      if not VarIsNull(fwPolicy2.Rules) and (fwPolicy2.Rules.Count > 0) then
      begin
        // 从索引0开始遍历(COM集合通常以0为起始)
        for i := 0 to fwPolicy2.Rules.Count - 1 do
        begin
          rule := fwPolicy2.Rules.Item(i);
          // 确保rule对象有效再访问属性
          if not VarIsNull(rule) then
          begin
            if rule.Direction = NET_FW_RULE_DIR_OUT then
            begin
              Result.Add(rule.Name);
            end;
          end;
        end;
      end;
    except
      on E: EOleException do
      begin
        Result.Free;
        raise Exception.CreateFmt('访问防火墙规则错误: %s', [E.Message]);
      end;
      on E: Exception do
      begin
        Result.Free;
        raise;
      end;
    end;
  finally
    CoUninitialize;
  end;
end;

方案2:使用强类型NetFwTypeLib(推荐)

导入官方的Windows防火墙类型库,用强类型对象访问,避免OleVariant的兼容性问题:

  1. 导入类型库:

    • 打开Delphi,依次点击Component -> Import Component -> Import a Type Library
    • 在列表中找到Windows Firewall with Advanced Security(或NetFwTypeLib),导入生成单元(默认命名为NetFwLib.pas)
  2. 实现代码:

uses
  SysUtils, Classes, ActiveX, NetFwLib;

function GetOutboundFirewallRuleNames: TStringList;
var
  i: Integer;
  fwPolicy2: INetFwPolicy2;
  rules: INetFwRules;
  rule: INetFwRule;
begin
  Result := TStringList.Create;
  try
    // 初始化单线程公寓模型COM
    if CoInitializeEx(nil, COINIT_APARTMENTTHREADED) <> S_OK then
      raise Exception.Create('COM初始化失败');
    try
      // 创建强类型防火墙策略对象
      fwPolicy2 := CoNetFwPolicy2.Create;
      rules := fwPolicy2.Rules;
      
      for i := 0 to rules.Count - 1 do
      begin
        rule := rules.Item(i);
        if rule.Direction = NET_FW_RULE_DIR_OUT then
        begin
          Result.Add(rule.Name);
        end;
      end;
    except
      on E: EOleException do
      begin
        Result.Free;
        raise Exception.CreateFmt('访问防火墙规则错误: %s', [E.Message]);
      end;
      on E: Exception do
      begin
        Result.Free;
        raise;
      end;
    end;
  finally
    CoUninitialize;
  end;
end;

注意事项

  • 必须以管理员权限运行程序,否则会被系统拒绝访问防火墙规则。
  • 确保Windows Firewall服务(MpsSvc)处于运行状态。
  • 编译时注意目标平台(32/64位),避免与COM对象位数不匹配。

内容的提问来源于stack exchange,提问作者Shaun Roselt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 17:52:29