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

如何用C++检测Win10/11特定网络连接的DNS获取模式(自动/手动)

如何用C++检查Windows 10/11特定网络连接的DNS配置类型

要准确判断Windows 10/11中特定网络连接的DNS是自动获取还是手动设置,推荐结合GetAdaptersAddresses和GetInterfaceDnsSettings两个API——前者用于定位目标网络适配器,后者用于获取该适配器的DNS配置详情及来源标识。

核心思路

  1. 调用GetAdaptersAddresses获取系统中所有网络适配器的基础信息,通过适配器名称(友好名或GUID)定位目标设备。
  2. 针对目标适配器的LUID,调用GetInterfaceDnsSettings获取DNS配置结构体INTERFACE_DNS_SETTINGS。
  3. 检查结构体中的Flags字段:若包含DNS_SETTING_FLAG_DNS_SERVER_AUTO_CONFIGURED,则DNS为自动获取(来自DHCP、RA等);反之则为手动设置。

完整代码示例

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

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

BOOL CheckDnsConfiguration(const wchar_t* targetAdapterName) {
    DWORD bufferSize = 0;
    // 先获取所需缓冲区大小
    GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, NULL, &bufferSize);
    PIP_ADAPTER_ADDRESSES adapterList = (PIP_ADAPTER_ADDRESSES)malloc(bufferSize);
    if (!adapterList) {
        printf("内存分配失败\n");
        return FALSE;
    }

    if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, adapterList, &bufferSize) != NO_ERROR) {
        free(adapterList);
        printf("获取适配器列表失败,错误码: %d\n", GetLastError());
        return FALSE;
    }

    // 遍历适配器列表,定位目标设备
    PIP_ADAPTER_ADDRESSES currAdapter = adapterList;
    while (currAdapter) {
        // 匹配友好名称(可替换为AdapterName用GUID匹配,更精准)
        if (_wcsicmp(currAdapter->FriendlyName, targetAdapterName) == 0) {
            INTERFACE_DNS_SETTINGS dnsSettings = {0};
            dnsSettings.Size = sizeof(INTERFACE_DNS_SETTINGS);
            
            if (GetInterfaceDnsSettings(currAdapter->Luid, &dnsSettings) == NO_ERROR) {
                if (dnsSettings.Flags & DNS_SETTING_FLAG_DNS_SERVER_AUTO_CONFIGURED) {
                    printf("该网络连接的DNS配置为自动获取\n");
                } else {
                    printf("该网络连接的DNS配置为手动设置\n");
                    // 打印手动配置的DNS服务器
                    for (DWORD i = 0; i < dnsSettings.DnsServerListCount; i++) {
                        wchar_t ipBuffer[46]; // 兼容IPv4/IPv6地址长度
                        DWORD bufLen = sizeof(ipBuffer) / sizeof(wchar_t);
                        if (WSAAddressToString(dnsSettings.DnsServerList[i].Address.lpSockaddr,
                            dnsSettings.DnsServerList[i].Address.iSockaddrLength,
                            NULL, ipBuffer, &bufLen) == 0) {
                            wprintf(L"手动DNS服务器[%d]: %s\n", i+1, ipBuffer);
                        }
                    }
                }
            } else {
                printf("获取DNS配置失败,错误码: %d\n", GetLastError());
            }
            free(adapterList);
            return TRUE;
        }
        currAdapter = currAdapter->Next;
    }

    printf("未找到指定名称的网络适配器\n");
    free(adapterList);
    return FALSE;
}

int main() {
    // 替换为你的目标网络连接友好名,比如L"以太网"、L"WLAN"
    CheckDnsConfiguration(L"WLAN");
    return 0;
}

关键说明

  • API版本要求:GetInterfaceDnsSettings仅支持Windows 10 1709及以上版本,若需兼容更早系统,可通过检查适配器的DHCP状态(IP_ADAPTER_ADDRESSES中的Dhcpv4Server/Dhcpv6Server是否非空)间接判断,但这种方式无法区分"DHCP启用但手动设置DNS"的场景。
  • 适配器匹配:用AdapterName(GUID格式)匹配比友好名更精准,避免同名适配器混淆,只需将代码中的FriendlyName替换为AdapterName即可。
  • 权限问题:无需管理员权限即可获取大部分适配器的DNS配置信息,但部分特殊适配器(如VPN)可能需要 elevated 权限。

为何旧API无法得到预期结果

GetAdaptersInfo是仅支持IPv4的旧API,它只能返回当前生效的DNS服务器列表,无法区分这些服务器是手动配置还是自动获取的,因此无法满足你的需求。而GetInterfaceDnsSettings专门用于获取DNS配置的元数据(包括配置来源),是Windows 10+平台的首选方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 12:05:31