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

如何使用C++修改与设置Windows系统的DNS地址

Windows平台C++修改DNS实现方案

前置要求

  • 编译时需链接wbemuuid.lib和iphlpapi.lib库,上述代码已通过pragma指令自动配置链接
  • 程序必须以管理员权限运行,否则WMI调用会因权限不足失败
  • 仅支持Windows操作系统,实现逻辑与你提供的C#代码完全对齐

完整实现代码

#include <windows.h>
#include <wbemcli.h>
#include <iphlpapi.h>
#include <iostream>
#include <vector>
#include <string>

#pragma comment(lib, "wbemuuid.lib")
#pragma comment(lib, "iphlpapi.lib")

// 获取符合条件的活动以太网/WiFi网卡描述
std::wstring GetActiveNetworkInterfaceDesc() {
    ULONG bufLen = 0;
    GetAdaptersInfo(NULL, &bufLen);
    std::vector<BYTE> buf(bufLen);
    PIP_ADAPTER_INFO pAdapterInfo = reinterpret_cast<PIP_ADAPTER_INFO>(buf.data());
    
    if (GetAdaptersInfo(pAdapterInfo, &bufLen) != ERROR_SUCCESS) {
        return L"";
    }

    while (pAdapterInfo) {
        // 筛选条件:状态连通、类型为以太网/WiFi、存在IPv4网关
        if (pAdapterInfo->OperStatus == IfOperStatusUp && 
            (pAdapterInfo->Type == MIB_IF_TYPE_ETHERNET || pAdapterInfo->Type == IF_TYPE_IEEE80211)) {
            if (pAdapterInfo->GatewayList.IpAddress.String[0] != '\0') {
                // 网卡描述转为宽字符返回
                int len = MultiByteToWideChar(CP_ACP, 0, pAdapterInfo->Description, -1, NULL, 0);
                std::wstring desc(len, 0);
                MultiByteToWideChar(CP_ACP, 0, pAdapterInfo->Description, -1, desc.data(), len);
                return desc;
            }
        }
        pAdapterInfo = pAdapterInfo->Next;
    }
    return L"";
}

// 设置指定网卡DNS
bool SetDNS(const std::wstring& dnsAddr) {
    std::wstring targetDesc = GetActiveNetworkInterfaceDesc();
    if (targetDesc.empty()) {
        std::wcout << L"未找到符合条件的活动网卡" << std::endl;
        return false;
    }

    HRESULT hres;
    hres = CoInitializeEx(0, COINIT_MULTITHREADED);
    if (FAILED(hres)) {
        return false;
    }

    hres = CoInitializeSecurity(
        NULL,
        -1,
        NULL,
        NULL,
        RPC_C_AUTHN_LEVEL_DEFAULT,
        RPC_C_IMP_LEVEL_IMPERSONATE,
        NULL,
        EOAC_NONE,
        NULL
    );
    if (FAILED(hres)) {
        CoUninitialize();
        return false;
    }

    IWbemLocator* pLoc = NULL;
    hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc);
    if (FAILED(hres)) {
        CoUninitialize();
        return false;
    }

    IWbemServices* pSvc = NULL;
    hres = pLoc->ConnectServer(
        _bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &pSvc);
    if (FAILED(hres)) {
        pLoc->Release();
        CoUninitialize();
        return false;
    }

    hres = CoSetProxyBlanket(
        pSvc,
        RPC_C_AUTHN_WINNT,
        RPC_C_AUTHZ_NONE,
        NULL,
        RPC_C_AUTHN_LEVEL_CALL,
        RPC_C_IMP_LEVEL_IMPERSONATE,
        NULL,
        EOAC_NONE
    );
    if (FAILED(hres)) {
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return false;
    }

    IEnumWbemClassObject* pEnumerator = NULL;
    hres = pSvc->ExecQuery(
        _bstr_t(L"WQL"),
        _bstr_t(L"SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = TRUE"),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
        NULL,
        &pEnumerator
    );
    if (FAILED(hres)) {
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return false;
    }

    IWbemClassObject* pclsObj = NULL;
    ULONG uReturn = 0;
    bool success = false;

    while (pEnumerator) {
        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
        if (uReturn == 0) break;

        VARIANT vtDesc;
        VariantInit(&vtDesc);
        hr = pclsObj->Get(L"Description", 0, &vtDesc, 0, 0);
        if (SUCCEEDED(hr) && wcscmp(vtDesc.bstrVal, targetDesc.c_str()) == 0) {
            IWbemClassObject* pClass = NULL;
            hr = pSvc->GetObject(_bstr_t(L"Win32_NetworkAdapterConfiguration"), 0, NULL, &pClass, NULL);
            if (SUCCEEDED(hr)) {
                IWbemClassObject* pInParamsDefinition = NULL;
                hr = pClass->GetMethod(L"SetDNSServerSearchOrder", 0, &pInParamsDefinition, NULL);
                if (SUCCEEDED(hr)) {
                    IWbemClassObject* pInstance = NULL;
                    hr = pInParamsDefinition->SpawnInstance(0, &pInstance);
                    if (SUCCEEDED(hr)) {
                        // 构造DNS地址数组
                        SAFEARRAY* psaDns = SafeArrayCreateVector(VT_BSTR, 0, 1);
                        LONG index = 0;
                        BSTR bstrDns = SysAllocString(dnsAddr.c_str());
                        SafeArrayPutElement(psaDns, &index, bstrDns);
                        
                        VARIANT vtDns;
                        VariantInit(&vtDns);
                        vtDns.vt = VT_ARRAY | VT_BSTR;
                        vtDns.parray = psaDns;
                        
                        hr = pInstance->Put(L"DNSServerSearchOrder", 0, &vtDns, 0);
                        if (SUCCEEDED(hr)) {
                            VARIANT vtPath;
                            VariantInit(&vtPath);
                            hr = pclsObj->Get(L"__PATH", 0, &vtPath, 0, 0);
                            if (SUCCEEDED(hr)) {
                                IWbemClassObject* pOutParams = NULL;
                                hr = pSvc->ExecMethod(vtPath.bstrVal, _bstr_t(L"SetDNSServerSearchOrder"), 0, NULL, pInstance, &pOutParams, NULL);
                                if (SUCCEEDED(hr)) {
                                    VARIANT vtRet;
                                    VariantInit(&vtRet);
                                    hr = pOutParams->Get(L"ReturnValue", 0, &vtRet, NULL, 0);
                                    if (SUCCEEDED(hr) && vtRet.lVal == 0) {
                                        success = true;
                                    }
                                    VariantClear(&vtRet);
                                    pOutParams->Release();
                                }
                                VariantClear(&vtPath);
                            }
                        }
                        VariantClear(&vtDns);
                        SafeArrayDestroy(psaDns);
                        SysFreeString(bstrDns);
                        pInstance->Release();
                    }
                    pInParamsDefinition->Release();
                }
                pClass->Release();
            }
        }
        VariantClear(&vtDesc);
        pclsObj->Release();
    }

    pEnumerator->Release();
    pSvc->Release();
    pLoc->Release();
    CoUninitialize();
    return success;
}

// 调用示例
int main() {
    // 示例设置为阿里公共DNS,可替换为需要的DNS地址
    if (SetDNS(L"223.5.5.5")) {
        std::wcout << L"DNS设置成功" << std::endl;
    } else {
        std::wcout << L"DNS设置失败,请确认以管理员权限运行程序" << std::endl;
    }
    system("pause");
    return 0;
}

扩展说明

如果需要配置多个DNS地址,仅需调整SafeArrayCreateVector的长度参数,按顺序将多个DNS地址填入数组即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 17:36:03