Windows中通过C++自动添加防火墙例外规则

在C++程序中无法直接控制防火墙警报窗口的显示,因为这是由操作系统和防火墙软件控制的。防火墙警报窗口是为了提醒用户程序正在尝试与外部网络进行通信,以确保用户意识到可能的网络活动。

然而,可以通过编写C++程序在用户的系统上自动添加防火墙例外规则,从而避免防火墙警报窗口的显示,以下是代码示例方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
#include <Windows.h>
#include <netfw.h>
 
int add_firewall_whitelist()
{
    // 初始化COM库
    HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    if (SUCCEEDED(hr)) {
        // 创建INetFwPolicy2对象
        INetFwPolicy2* pFwPolicy = nullptr;
        hr = CoCreateInstance(__uuidof(NetFwPolicy2), nullptr, CLSCTX_INPROC_SERVER,
            __uuidof(INetFwPolicy2), reinterpret_cast<void**>(&pFwPolicy));
        if (SUCCEEDED(hr)) {
            // 创建规则对象
            INetFwRule* pFwRule = nullptr;
            hr = CoCreateInstance(__uuidof(NetFwRule), nullptr, CLSCTX_INPROC_SERVER,
                __uuidof(INetFwRule), reinterpret_cast<void**>(&pFwRule));
            if (SUCCEEDED(hr)) {
                // 配置规则属性
                BSTR ruleName = SysAllocString(L"MyAppRule");
                pFwRule->put_Name(ruleName);
                SysFreeString(ruleName);
 
                BSTR exePath = SysAllocString(L"C:\\Path\\To\\Your\\Program.exe");// 替换为你的程序路径
                pFwRule->put_ApplicationName(exePath);
                pFwRule->put_Action(NET_FW_ACTION_ALLOW);
                pFwRule->put_Direction(NET_FW_RULE_DIR_IN);
                pFwRule->put_Enabled(VARIANT_TRUE);
                pFwRule->put_Profiles(NET_FW_PROFILE2_ALL);
 
                // 将规则添加到防火墙策略中
                INetFwRules* pFwRules = NULL;
                hr = pFwPolicy->get_Rules(&pFwRules);
                if (SUCCEEDED(hr)) {
                    hr = pFwRules->Add(pFwRule);
                    if (SUCCEEDED(hr)) {
                        std::cout << "Rule added successfully" << std::endl;
                    }
                    pFwRules->Release();
                }
                SysFreeString(exePath);
                pFwRule->Release();
            }
 
            pFwPolicy->Release();
        }
        // 释放COM库资源
        CoUninitialize();
    }
    return 0; 
}

 下面是传入参数的形式向防火墙中添加例外规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <iostream>
#include <Windows.h>
#include <netfw.h>
#include <string.h>
#include <tchar.h>
#include <fstream>
 
int main(int argc, char* argv[]) {
    /* 打开文件以写入 */
    std::ofstream outputFile("firewall_setting.log", std::ios::app);
    if (outputFile.is_open()) {
        if (argc != 3) {
            outputFile << "The parameter is invalid" << std::endl;
            outputFile.close();
 
            return 1;
        }
        /* 写入数据 */
        outputFile << argv[0] << std::endl;
        outputFile << argv[1] << std::endl;
    }
 
    /* 初始化COM库 */
    HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    if (SUCCEEDED(hr)) {
        /* 创建INetFwPolicy2对象 */
        INetFwPolicy2* pFwPolicy = nullptr;
        hr = CoCreateInstance(__uuidof(NetFwPolicy2), nullptr, CLSCTX_INPROC_SERVER,
            __uuidof(INetFwPolicy2), reinterpret_cast<void**>(&pFwPolicy));
        if (SUCCEEDED(hr)) {
            for (int i = 0; i < argc; ++i) {
                if (i == 0) {
                    continue;
                }
 
                /* 创建规则对象 */
                INetFwRule* pFwRule = nullptr;
                hr = CoCreateInstance(__uuidof(NetFwRule), nullptr, CLSCTX_INPROC_SERVER,
                    __uuidof(INetFwRule), reinterpret_cast<void**>(&pFwRule));
               
                wchar_t exeName[128] = { 0 };;
                size_t convertedChars = 0;
                errno_t result = mbstowcs_s(&convertedChars, exeName, strlen(argv[i]) + 1, argv[i], _TRUNCATE);
                if (result == 0) {
                    outputFile << "Converted characters:" << convertedChars << std::endl;
                    /* 配置指定规则属性 */
                    TCHAR* lastBackslash = _tcsrchr(exeName, '.');
                    if (lastBackslash != nullptr) {
                        *lastBackslash = '\0'; // 将路径中的最后一个反斜杠替换为字符串终止符
                    }
                    outputFile << "current work dir:" << exeName << std::endl;
 
                    BSTR ruleName = SysAllocString(exeName);
                    pFwRule->put_Name(ruleName);
                    SysFreeString(ruleName);
 
                    // 获取当前可执行文件的路径
                    TCHAR buffer[MAX_PATH] = { 0 };
                    DWORD pathLength = GetModuleFileName(NULL, buffer, MAX_PATH);
                    if (pathLength > 0) {
                        // 从路径中提取工作目录部分
                        lastBackslash = _tcsrchr(buffer, '\\');
                        if (lastBackslash != nullptr) {
                            *lastBackslash = '\0'; // 将路径中的最后一个反斜杠替换为字符串终止符
                        }
                    }
 
                    wchar_t rulePath[128] = { 0 };;
                    result = mbstowcs_s(&convertedChars, rulePath, strlen(argv[i]) + 1, argv[i], _TRUNCATE);
                    if (result == 0) {
                        TCHAR str1[28] = L"\\";
                        _tcscat_s(buffer, MAX_PATH, str1);
                        _tcscat_s(buffer, MAX_PATH, rulePath);
                        BSTR exePath = SysAllocString(buffer);
                        pFwRule->put_ApplicationName(exePath);
                        pFwRule->put_Action(NET_FW_ACTION_ALLOW);
                        pFwRule->put_Direction(NET_FW_RULE_DIR_IN);
                        pFwRule->put_Enabled(VARIANT_TRUE);
                        pFwRule->put_Profiles(NET_FW_PROFILE2_ALL);
 
                        /* 将规则添加到防火墙策略中 */
                        INetFwRules* pFwRules = nullptr;
                        hr = pFwPolicy->get_Rules(&pFwRules);
                        if (SUCCEEDED(hr)) {
                            hr = pFwRules->Add(pFwRule);
                            if (SUCCEEDED(hr)) {
                                outputFile << "Rule added successfully" << std::endl;
                            }
                            else {
                                outputFile << "Rule added Failed" << std::endl;
                            }
                            pFwRules->Release();
                        }
                        SysFreeString(exePath);
                    }
                }
                else {
                    outputFile << "mbstowcs_s failed with error code :" << result << std::endl;
                }
                pFwRule->Release();
            }
            pFwPolicy->Release();
        }
        else {
            outputFile << "Failed to create INetFwPolicy2 object" << std::endl;
        }
        /* 释放COM库资源 */
        CoUninitialize();
    }
    else {
        outputFile << "Failed to initialize COM library" << std::endl;
    }
 
    /* 关闭文件 */
    outputFile.close();
 
    return 1;
}

  

posted @   TechNomad  阅读(260)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示