【问题标题】:How to Open Port in Windows Firewall using C++ Builder?如何使用 C++ Builder 在 Windows 防火墙中打开端口?
【发布时间】:2019-12-22 22:24:14
【问题描述】:

当我在 Borland C++Builder 中编译我的项目时出现错误:

“添加”不是“变体”的成员

我尝试使用自动化 API 执行此操作,但它给了我上面的错误:

const NET_FW_PROFILE2_DOMAIN  = 1;
const NET_FW_PROFILE2_PRIVATE = 2;
const NET_FW_PROFILE2_PUBLIC  = 4;

const NET_FW_IP_PROTOCOL_TCP = 6;
const NET_FW_IP_PROTOCOL_UDP = 17;
const NET_FW_ACTION_ALLOW    = 1;
const NET_FW_RULE_DIR_IN  = 1;
const NET_FW_RULE_DIR_OUT = 2;

Variant fwPolicy2, RulesObject, NewRule;
DWORD Profile;

Profile   = NET_FW_PROFILE2_PRIVATE | NET_FW_PROFILE2_PUBLIC;
fwPolicy2 = CreateOleObject("HNetCfg.FwPolicy2");
RulesObject = fwPolicy2.OlePropertyGet("Rules");
NewRule   = CreateOleObject("HNetCfg.FWRule");
NewRule.OlePropertyGet("Name") = "Text Firewall";
NewRule.OlePropertyGet("Description") = "Text Firewall";
NewRule.OlePropertyGet("Applicationname") = "System_RCC.exe";
NewRule.OlePropertyGet("Protocol")   = NET_FW_IP_PROTOCOL_TCP;
NewRule.OlePropertyGet("LocalPorts") = Edit1->Text;
NewRule.OlePropertyGet("Direction")  = NET_FW_RULE_DIR_OUT;
NewRule.OlePropertyGet("Enabled")   = true;
NewRule.OlePropertyGet("Grouping")  = "";
NewRule.OlePropertyGet("Profiles")  = Profile;
NewRule.OlePropertyGet("Action")  = NET_FW_ACTION_ALLOW;
RulesObject.Add(NewRule);

注意:此代码取自这里:

How to open port in Win7 Firewall using Delphi

【问题讨论】:

    标签: c++builder


    【解决方案1】:

    RulesObject 是一个包装 COM 对象的 System::Variant

    在 Delphi 中,(Ole)Variant 为您透明地处理对 COM 对象的属性和方法的访问(编译器将调用转换为对 IDispatch::GetIDsOfNames()IDispatch::Invoke() 接口方法的调用)。这就是为什么您链接到的 Delphi 代码非常简单。

    然而,在 C++ 中,您必须使用 Variant::OleProcedure()Variant::OleFunction() 方法来调用 COM 对象的方法,就像您必须使用 Variant::OleProperty(Get|Set)() 方法来访问 COM 对象的属性一样。 Variant::Ole...() 方法执行类似于 Delphi 执行的 IDispatch 调用。

    另外,填充NewRule时,需要使用OlePropertySet()而不是OlePropertyGet()

    试试这个:

    const NET_FW_PROFILE2_DOMAIN = 1;
    const NET_FW_PROFILE2_PRIVATE = 2;
    const NET_FW_PROFILE2_PUBLIC = 4;
    
    const NET_FW_IP_PROTOCOL_TCP = 6;
    const NET_FW_IP_PROTOCOL_UDP = 17;
    const NET_FW_ACTION_ALLOW = 1;
    const NET_FW_RULE_DIR_IN = 1;
    const NET_FW_RULE_DIR_OUT = 2;
    
    Variant fwPolicy2, RulesObject, NewRule;
    DWORD Profile;
    
    Profile = NET_FW_PROFILE2_PRIVATE | NET_FW_PROFILE2_PUBLIC;
    fwPolicy2 = CreateOleObject("HNetCfg.FwPolicy2"); RulesObject = fwPolicy2.OlePropertyGet("Rules");
    NewRule = CreateOleObject("HNetCfg.FWRule");
    NewRule.OlePropertySet("Name", WideString("Text Firewall"));
    NewRule.OlePropertySet("Description", WideString("Text Firewall"));
    NewRule.OlePropertySet("Applicationname", WideString("System_RCC.exe"));
    NewRule.OlePropertySet("Protocol", NET_FW_IP_PROTOCOL_TCP);
    NewRule.OlePropertySet("LocalPorts", Edit1->Text);
    NewRule.OlePropertySet("Direction", NET_FW_RULE_DIR_OUT);
    NewRule.OlePropertySet("Enabled", true);
    NewRule.OlePropertySet("Grouping", WideString(""));
    NewRule.OlePropertySet("Profiles", Profile);
    NewRule.OlePropertySet("Action", NET_FW_ACTION_ALLOW);
    RulesObject.OleProcedure("Add", NewRule);
    

    【讨论】:

    • 现在我在RulesObject.OleProcedure("Add", NewRule); 得到一个异常,说参数不正确First chance exception at $7579AA12. Exception class EOleException with message 'The parameter is incorrect'. Process Project1.exe (10100)
    • 谢谢,虽然解决了,但是忘记加NewRule.OlePropertySet("LocalPorts", WideString(Edit1->Text));,还需要管理员权限
    • @Jack Edit1->Text 返回一个System::String,在调用Variant::Ole...() 方法时不需要显式转换为WideStringVariant 将正确处理String 数据。 char* 字符串(例如字符串文字)并非如此,它们没有作为字符串正确中断,因此显式转换为 WideString。是的,当然需要管理员权限才能修改防火墙设置
    猜你喜欢
    • 1970-01-01
    • 2016-06-06
    • 1970-01-01
    • 2013-12-02
    • 2012-08-16
    • 2015-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多