You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

NetworkInterface.GetAllNetworkInterfaces与ipconfig /all结果不一致问题求助

解决NetworkInterface与ipconfig /all返回网络适配器信息不一致的问题

我看到你在C# WPF程序里遇到了一个头疼的问题:用NetworkInterface.GetAllNetworkInterfaces()拿到的网络适配器信息,和ipconfig /all的输出对不上——部分适配器的描述字段不符、DNS后缀缺失,甚至物理地址格式也不一样。别着急,咱们来一步步把这个问题搞定。

问题根源分析

你原来的代码里有几个关键的小问题,导致了信息不匹配:

  • 你用了adapter.Name作为适配器描述,但这个属性是系统内部的标识符(比如Ethernet0),而ipconfig里显示的是设备的友好描述,对应adapter.Description属性。
  • 物理地址的默认ToString()输出是无分隔的十六进制字符串,和ipconfig里的冒号分隔格式不一致,而且没处理空地址的情况。
  • 连接特定DNS后缀只取了全局的properties.DnsSuffix,但有些适配器的后缀信息存在于单播IPv4地址的属性里,全局字段为空。
  • 没有过滤掉回环、未启用的适配器,导致结果里包含了ipconfig不会显示的无效设备。

修改后的完整代码

先调整数据存储类(用属性更符合C#规范):

class MacAddress
{
    public string ConnectionSpecificDnsSuffix { get; set; }
    public string Description { get; set; }
    public string PhysicalAddress { get; set; }
}

然后重写GetMacAddresses方法,修复上述问题:

internal List<MacAddress> GetMacAddresses()
{
    NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
    List<MacAddress> macAddresses = new List<MacAddress>();

    foreach (NetworkInterface adapter in nics)
    {
        // 过滤掉回环、未启用的适配器,和ipconfig输出逻辑对齐
        if (adapter.NetworkInterfaceType == NetworkInterfaceType.Loopback || 
            adapter.OperationalStatus != OperationalStatus.Up)
        {
            continue;
        }

        IPInterfaceProperties properties = adapter.GetIPProperties();
        MacAddress address = new MacAddress();

        // 优先从IPv4单播地址获取连接特定DNS后缀,全局字段为空时用这个
        string dnsSuffix = properties.DnsSuffix;
        foreach (var unicastAddr in properties.UnicastAddresses)
        {
            if (unicastAddr.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
            {
                var ipv4Props = unicastAddr.GetIPv4Properties();
                if (!string.IsNullOrEmpty(ipv4Props.DnsSuffix))
                {
                    dnsSuffix = ipv4Props.DnsSuffix;
                    break;
                }
            }
        }
        address.ConnectionSpecificDnsSuffix = string.IsNullOrEmpty(dnsSuffix) ? "无" : dnsSuffix;

        // 用Description获取和ipconfig一致的适配器描述
        address.Description = adapter.Description;

        // 格式化物理地址为ipconfig的冒号分隔格式,处理空地址情况
        PhysicalAddress physAddr = adapter.GetPhysicalAddress();
        byte[] addrBytes = physAddr.GetAddressBytes();
        address.PhysicalAddress = addrBytes.Length > 0 
            ? string.Join(":", addrBytes.Select(b => b.ToString("X2"))) 
            : "无";

        macAddresses.Add(address);
    }

    return macAddresses;
}

最后调整按钮点击事件的逻辑,避免跳过第一个适配器:

private void detectButton_Click(object sender, RoutedEventArgs e)
{
    List<MacAddress> macAddresses = GetMacAddresses();
    
    // 遍历所有检测到的适配器,对应label1、label2...
    for (int i = 0; i < macAddresses.Count; i++)
    {
        Label label = (Label)this.FindName("label" + (i + 1).ToString());
        if (label != null)
        {
            label.Content = $"Connection Specific DNS suffix: {macAddresses[i].ConnectionSpecificDnsSuffix}\n" +
                           $"Description: {macAddresses[i].Description}\n" +
                           $"Physical Address: {macAddresses[i].PhysicalAddress}";
        }
    }

    MessageBox.Show($"共检测到{macAddresses.Count}个活动网络适配器");
}

为什么这些修改有效?

  • 适配器描述adapter.Description返回的是设备管理器中显示的友好名称,和ipconfig /all里的“描述”字段完全匹配,再也不会出现名称不符的情况。
  • 物理地址格式:通过把字节数组转换成带冒号的十六进制字符串,输出格式和ipconfig完全一致,同时处理了空地址的边界情况。
  • DNS后缀准确性:优先从IPv4单播地址的属性中获取后缀,覆盖了全局字段为空的场景,确保拿到的是和ipconfig一致的连接特定DNS后缀。
  • 过滤无效适配器:只保留启用的非回环适配器,结果和ipconfig显示的活动设备完全对齐。

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

火山引擎 最新活动