发布于2026-07-19 阅读(0)
扫一扫,手机访问
### 用 `NetworkInterface` 获取本机主网卡 MAC 地址(最常用)
说白了,大多数情况下你要的其实很简单——就是当前正在上网的那块网卡的物理地址。直接遍历所有`NetworkInterface`并过滤掉虚拟、环回、未连接的接口,是最可靠的做法。
具体来说,你需要:
- 优先选`OperationalStatus.Up`且`NetworkInterfaceType.Ethernet`或`NetworkInterfaceType.Wireless80211`的网卡
- 跳过`NetworkInterfaceType.Loopback`、`NetworkInterfaceType.Tunnel`、`NetworkInterfaceType.Unknown`类型
- 排除空MAC(`GetPhysicalAddress().ToString()`返回`"000000000000"`)
然后按`Speed`降序排列,取第一个,就是你要的主网卡。代码写起来也很直白:
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();
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种方法”,其中两种在新项目里基本不该出现。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8