如何用C++检测Win10/11特定网络连接的DNS获取模式(自动/手动)
如何用C++检查Windows 10/11特定网络连接的DNS配置类型
要准确判断Windows 10/11中特定网络连接的DNS是自动获取还是手动设置,推荐结合GetAdaptersAddresses和GetInterfaceDnsSettings两个API——前者用于定位目标网络适配器,后者用于获取该适配器的DNS配置详情及来源标识。
核心思路
- 调用
GetAdaptersAddresses获取系统中所有网络适配器的基础信息,通过适配器名称(友好名或GUID)定位目标设备。 - 针对目标适配器的LUID,调用
GetInterfaceDnsSettings获取DNS配置结构体INTERFACE_DNS_SETTINGS。 - 检查结构体中的
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
相关产品推荐
相关产品推荐

