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

使用SetInterfaceDnsSettings/GetInterfaceDnsSettings修改Windows DNS的C++问题

C++调用SetInterfaceDnsSettings/GetInterfaceDnsSettings的正确示例

错误原因分析

  • GetInterfaceDnsSettings返回87(ERROR_INVALID_PARAMETER):通常是未正确初始化INTERFACE_DNS_SETTINGS结构体的Version字段,或者传入的网络接口索引无效。
  • SetInterfaceDnsSettings返回0但未生效:大概率是未指定正确的Flags(如未标记要修改DNS服务器地址),或者程序未以管理员权限运行。

完整示例代码

以下代码包含获取有效网络接口索引、调用GetInterfaceDnsSettings读取当前DNS,以及调用SetInterfaceDnsSettings修改DNS的完整流程:

#include <windows.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

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

// 获取第一个启用的以太网/Wi-Fi接口索引
DWORD GetActiveNetworkInterfaceIndex() {
    DWORD dwSize = 0;
    GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_INTERFACES, NULL, NULL, &dwSize);
    
    PIP_ADAPTER_ADDRESSES pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(dwSize);
    if (!pAddresses) {
        return 0;
    }

    if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_INTERFACES, NULL, pAddresses, &dwSize) != NO_ERROR) {
        free(pAddresses);
        return 0;
    }

    DWORD index = 0;
    for (PIP_ADAPTER_ADDRESSES pCurr = pAddresses; pCurr != NULL; pCurr = pCurr->Next) {
        // 筛选启用的以太网或Wi-Fi接口
        if (pCurr->OperStatus == IfOperStatusUp && 
            (pCurr->IfType == IF_TYPE_ETHERNET_CSMACD || pCurr->IfType == IF_TYPE_IEEE80211)) {
            index = pCurr->IfIndex;
            break;
        }
    }

    free(pAddresses);
    return index;
}

int main() {
    DWORD dwInterfaceIndex = GetActiveNetworkInterfaceIndex();
    if (dwInterfaceIndex == 0) {
        printf("未找到有效网络接口\n");
        return 1;
    }
    printf("目标接口索引: %lu\n", dwInterfaceIndex);

    // 读取当前DNS配置
    INTERFACE_DNS_SETTINGS dnsSettings = {0};
    dnsSettings.Version = INTERFACE_DNS_SETTINGS_VERSION_1; // 必须指定正确版本

    DWORD dwResult = GetInterfaceDnsSettings(dwInterfaceIndex, &dnsSettings);
    if (dwResult != NO_ERROR) {
        printf("GetInterfaceDnsSettings 失败,错误码: %lu\n", dwResult);
        return 1;
    }

    if (dnsSettings.NameServer[0]) {
        printf("当前DNS服务器: %s\n", dnsSettings.NameServer);
    } else {
        printf("当前未设置DNS服务器\n");
    }

    // 修改DNS服务器地址
    INTERFACE_DNS_SETTINGS newDnsSettings = {0};
    newDnsSettings.Version = INTERFACE_DNS_SETTINGS_VERSION_1;
    newDnsSettings.Flags = DNS_SETTING_NAMESERVER; // 标记要修改DNS服务器项
    // 设置主备DNS,用空格分隔,确保不超出数组长度
    strncpy_s(newDnsSettings.NameServer, sizeof(newDnsSettings.NameServer), "8.8.8.8 8.8.4.4", _TRUNCATE);

    dwResult = SetInterfaceDnsSettings(dwInterfaceIndex, &newDnsSettings);
    if (dwResult != NO_ERROR) {
        printf("SetInterfaceDnsSettings 失败,错误码: %lu\n", dwResult);
        return 1;
    }
    printf("DNS服务器修改成功\n");

    // 验证修改结果
    ZeroMemory(&dnsSettings, sizeof(dnsSettings));
    dnsSettings.Version = INTERFACE_DNS_SETTINGS_VERSION_1;
    dwResult = GetInterfaceDnsSettings(dwInterfaceIndex, &dnsSettings);
    if (dwResult == NO_ERROR && dnsSettings.NameServer[0]) {
        printf("修改后DNS服务器: %s\n", dnsSettings.NameServer);
    }

    return 0;
}

关键注意事项

  • 管理员权限:修改DNS需要程序以管理员身份运行,否则SetInterfaceDnsSettings可能返回0但实际未生效。
  • 结构体Version字段:必须设置为INTERFACE_DNS_SETTINGS_VERSION_1(当前唯一可用版本),否则会触发参数错误。
  • Flags字段:调用SetInterfaceDnsSettings时,必须通过Flags明确指定要修改的配置项,比如DNS_SETTING_NAMESERVER对应DNS服务器地址,DNS_SETTING_SEARCHLIST对应DNS搜索列表。
  • 接口索引有效性:确保传入的接口索引对应存在且启用的网络接口,可通过GetAdaptersAddresses等API获取正确索引。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 04:20:23