最常用且推荐的方式是用 NetworkInterface 遍历过滤:取 OperationalStatus.Up 且为 Ethernet 或 Wireless80211 类型、MAC 非全零的网卡,按 Speed 降序取首个;WMI 方式适合需底层信息的诊断场景;IPGlobalProperties 不提供 MAC,误用易出错;.NET 6+ 跨平台需额外按名称过滤虚拟网卡。

用 NetworkInterface 获取本机主网卡 MAC 地址(最常用)
多数场景下,你真正需要的是「当前默认上网用的那块网卡」的物理地址。直接遍历所有 NetworkInterface 并过滤掉虚拟、环回、未连接的接口,是最可靠的做法。
- 优先选
OperationalStatus.Up且NetworkInterfaceType.Ethernet或NetworkInterfaceType.Wireless80211 - 跳过
NetworkInterfaceType.Loopback、NetworkInterfaceType.Tunnel、NetworkInterfaceType.Unknown - 排除空 MAC(
GetPhysicalAddress().ToString()返回"000000000000") - 示例片段:
var adapters = NetworkInterface.GetAllNetworkInterfaces() .Where(nic => nic.OperationalStatus == OperationalStatus.Up && (nic.NetworkInterfaceType == NetworkInterfaceType.Ethernet || nic.NetworkInterfaceType == NetworkInterfaceType.Wireless80211) && !nic.GetPhysicalAddress().ToString().Equals("000000000000", StringComparison.OrdinalIgnoreCase)) .OrderByDescending(nic => nic.Speed) // 优先取千兆网卡 .FirstOrDefault(); </li></ul><p>string mac = adapters?.GetPhysicalAddress().ToString() ?? string.Empty;用
ManagementObjectSearcher查询 WMI(适合需区分有线/无线或获取驱动信息)WMI 方式能拿到更底层字段,比如
AdapterType、MACAddress、NetEnabled,适合诊断类工具或需兼容旧系统(如 Windows 7)。- 需引用
System.Management,并添加 NuGet 包System.Management(.NET Core/.NET 5+ 必须) - 查询语句用
"SELECT MACAddress FROM Win32_NetworkAdapter WHERE NetEnabled = True AND MACAddress IS NOT NULL" - 注意:WMI 在某些精简版系统或权限受限环境可能被禁用,会抛
ManagementException - 返回的
MACAddress是带冒号格式(如"00:1A:2B:3C:4D:5E"),需清理后使用
用
IPGlobalProperties+GetUnicastAddresses()(不推荐用于 MAC 获取)这个 API 实际上不提供 MAC 地址——它只返回 IP 层信息(如本地 IPv4/IPv6 地址、跃点数等)。很多博客误传它能取 MAC,本质是混淆了
NetworkInterface和IPGlobalProperties的职责。-
IPGlobalProperties.GetIPGlobalProperties().GetUnicastAddresses()返回的是UnicastIPAddressInformation对象,没有PhysicalAddress字段 - 若强行调用
.Address只能得到 IP,不是 MAC - 容易踩坑:写完发现返回空或报
NullReferenceException,根源就是对象类型不对
跨平台方案:.NET 6+ 中用
NetworkInterface的兼容性要点.NET 5/6+ 已统一
NetworkInterface行为,但 Linux/macOS 下仍有细节差异:- Linux 上虚拟网卡(如
docker0、veth*)可能被识别为NetworkInterfaceType.Ethernet,需额外按名称过滤 - macOS 上 Wi-Fi 接口类型常为
NetworkInterfaceType.Other,不能只依赖NetworkInterfaceType.Wireless80211 - 建议加一层名称白名单:
!nic.Name.StartsWith("docker") && !nic.Name.StartsWith("veth") -
GetPhysicalAddress()在容器内可能返回000000000000(取决于 host 网络模式)
真实环境里,没有“一种方式通吃全部场景”。最稳的路径是:先用
NetworkInterface主流程,再按 OS 和部署环境补小判断逻辑。别迷信“5 种方法”,其中两种在新项目里基本不该出现。 - 需引用


















