最直接可靠获取mac地址的方式是使用networkinterface.getphysicaladdress(),需筛选operationalstatus.up、ethernet/wireless80211类型且非只接收的网卡,避免虚拟设备或全零地址。

用 NetworkInterface.GetPhysicalAddress() 获取网卡 MAC 地址
最直接、最可靠的方式就是调用 .NET 内置的 NetworkInterface 类。它不依赖注册表或 WMI,跨 .NET Framework / .NET Core / .NET 5+ 都能用,且返回的是真实的物理地址(前提是网卡驱动正常上报)。
常见错误是遍历所有网卡却没过滤掉虚拟设备或未连接状态,结果拿到 00-00-00-00-00-00 或 VMware/VirtualBox 的虚拟 MAC。
- 只取
OperationalStatus.Up且NetworkInterfaceType.Ethernet或NetworkInterfaceType.Wireless80211的接口 - 跳过
IsReceiveOnly为true的接口(某些隧道适配器会这样) -
GetPhysicalAddress().ToString()返回带短横线的格式(如"00-11-22-33-44-55"),如需无分隔符,用.Replace("-", "")
foreach (var ni in NetworkInterface.GetAllNetworkInterfaces())
{
if (ni.OperationalStatus == OperationalStatus.Up &&
(ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet ||
ni.NetworkInterfaceType == NetworkInterfaceType.Wireless80211) &&
!ni.IsReceiveOnly)
{
var mac = ni.GetPhysicalAddress().ToString();
Console.WriteLine(mac); // e.g. "A0-BB-CC-DD-EE-FF"
break; // 通常取第一个可用的即可
}
}
为什么 GetMacAddress() 这种封装函数经常出错
网上很多“一行获取 MAC”的封装,比如用 IPGlobalProperties.GetIPGlobalProperties().GetUnicastAddresses() 反推、或靠 Dns.GetHostEntry 查本机名再解析——这些方式本质是间接推导,不可靠。
典型问题包括:
- 多网卡时返回任意一个(可能是 Docker 虚拟网卡、Hyper-V 交换机、甚至已禁用但未卸载的旧驱动残留)
- IPv6 启用后,
GetUnicastAddresses()可能优先返回链路本地地址对应的接口,而该接口物理地址为空 - 某些企业环境禁用 DNS 查询,
Dns.GetHostEntry直接抛SocketException - 容器或 WSL2 环境下,宿主机代码看到的是虚拟网络栈,MAC 和物理机器完全无关
遇到 System.Net.NetworkInformation.NetworkInterface 返回空或全零怎么办
不是代码写错了,大概率是权限或驱动层面的问题。.NET 层面无法绕过操作系统对硬件信息的暴露限制。
排查重点在运行环境而非 C# 逻辑:
- 确认程序以普通用户权限运行时是否被策略限制(如某些终端管理软件会拦截
GetAdaptersAddresses系统调用) - 检查网卡驱动是否异常:设备管理器中看是否有黄色感叹号,或尝试更新/回滚驱动
- 某些精简版 Windows(如 LTSC 或 IoT Core)默认关闭了
Network Location Awareness服务,启动该服务后重试 - Unity IL2CPP 或 AOT 编译环境下,
NetworkInterface类的部分成员可能被剪裁,需在link.xml中保留
需要唯一标识设备?别只靠 MAC 地址
MAC 地址不是稳定可靠的设备 ID。网卡可更换、虚拟机可克隆、某些 Wi-Fi 网卡支持随机化 MAC(iOS/Android/macOS 默认开启,Windows 10/11 也可启用)。
如果目标是设备绑定或反作弊,应组合其他维度:
- 读取主板序列号(需管理员权限 + WMI:
Win32_BaseBoard.SerialNumber) - 获取磁盘卷 ID(
DriveInfo.VolumeSerialNumber,重启不变但重装系统会变) - 生成并持久化一个本地 GUID 到注册表或应用数据目录(最可控)
- 避免把 MAC 当作加密密钥或 Token 种子——它既不保密也不唯一
真正难处理的是那些允许用户随意改 MAC 的场景(比如用 devcon 或第三方工具),这时候任何基于物理标识的方案都会失效。











