在授權驗證、裝置識別、網路診斷等場景需取得本機網路資訊。本文提供跨平台相容的實作,涵蓋 IPv4/IPv6、多網卡、實體/虛擬介面過濾。
using System;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Management; // 需參考 System.Management.dll
public static class NetworkInfo
{
public static NetworkIdentity GetLocalIdentity()
{
return new NetworkIdentity
{
HostName = Dns.GetHostName(),
IpAddresses = GetIpAddresses(),
MacAddresses = GetMacAddresses()
};
}
// 取得所有非回環 IPv4/IPv6 位址
public static IPAddress[] GetIpAddresses()
{
return Dns.GetHostEntry(Dns.GetHostName())
.AddressList
.Where(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork ||
ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
.Where(ip => !IPAddress.IsLoopback(ip))
.ToArray();
}
// 取得實體網卡 MAC 位址(排除虛擬介面、隧道、回環)
public static PhysicalAddress[] GetMacAddresses()
{
return NetworkInterface.GetAllNetworkInterfaces()
.Where(nic => nic.OperationalStatus == OperationalStatus.Up)
.Where(nic => nic.NetworkInterfaceType != NetworkInterfaceType.Loopback)
.Where(nic => nic.NetworkInterfaceType != NetworkInterfaceType.Tunnel)
.Where(nic => !nic.Description.Contains("Virtual", StringComparison.OrdinalIgnoreCase))
.Where(nic => !nic.Description.Contains("Hyper-V", StringComparison.OrdinalIgnoreCase))
.Where(nic => nic.GetPhysicalAddress().Length > 0)
.Select(nic => nic.GetPhysicalAddress())
.Distinct()
.ToArray();
}
// 使用 WMI 取得啟用 IP 的網卡 MAC(舊版相容)
public static string GetMacByWmi()
{
try
{
using (var mc = new ManagementClass("Win32_NetworkAdapterConfiguration"))
using (var moc = mc.GetInstances())
{
foreach (ManagementObject mo in moc)
{
if (mo["IPEnabled"]?.ToString() == "True")
{
return mo["MacAddress"]?.ToString()?.Replace(":", "-");
}
}
}
}
catch { /* WMI 不可用時靜默失敗 */ }
return null;
}
}
public class NetworkIdentity
{
public string HostName { get; set; }
public IPAddress[] IpAddresses { get; set; }
public PhysicalAddress[] MacAddresses { get; set; }
public string PrimaryIpv4 => IpAddresses?.FirstOrDefault(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)?.ToString();
public string PrimaryMac => MacAddresses?.FirstOrDefault()?.ToString();
public override string ToString()
{
return $"Host: {HostName}\nIPv4: {PrimaryIpv4}\nMAC: {PrimaryMac}";
}
}
public class Program
{
public static void Main()
{
var info = NetworkInfo.GetLocalIdentity();
Console.WriteLine("=== 本機網路身分 ===");
Console.WriteLine($"主機名稱: {info.HostName}");
Console.WriteLine($"主要 IPv4: {info.PrimaryIpv4 ?? "N/A"}");
Console.WriteLine($"主要 MAC: {info.PrimaryMac ?? "N/A"}");
Console.WriteLine("\n所有 IP 位址:");
foreach (var ip in info.IpAddresses)
Console.WriteLine($" {ip} ({ip.AddressFamily})");
Console.WriteLine("\n所有 MAC 位址:");
foreach (var mac in info.MacAddresses)
Console.WriteLine($" {mac}");
}
}
=== 本機網路身分 ===
主機名稱: DESKTOP-ABC123
主要 IPv4: 192.168.1.105
主要 MAC: 00-1A-2B-3C-4D-5E
所有 IP 位址:
192.168.1.105 (InterNetwork)
fe80::1a2b:3c4d:5e6f:7890%12 (InterNetworkV6)
所有 MAC 位址:
00-1A-2B-3C-4D-5E
00-1A-2B-3C-4D-5F
public static NetworkDetail GetDetail(string macAddress)
{
var nic = NetworkInterface.GetAllNetworkInterfaces()
.FirstOrDefault(n => n.GetPhysicalAddress().ToString().Equals(macAddress, StringComparison.OrdinalIgnoreCase));
if (nic == null) return null;
var ipProps = nic.GetIPProperties();
var ipv4 = ipProps.UnicastAddresses
.FirstOrDefault(a => a.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork);
return new NetworkDetail
{
Name = nic.Name,
Description = nic.Description,
Mac = nic.GetPhysicalAddress().ToString(),
IpAddress = ipv4?.Address.ToString(),
SubnetMask = ipv4?.IPv4Mask.ToString(),
Gateway = ipProps.GatewayAddresses
.Where(g => g.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
.Select(g => g.Address.ToString())
.FirstOrDefault(),
DnsServers = ipProps.DnsAddresses
.Where(d => d.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
.Select(d => d.ToString())
.ToArray(),
IsDhcpEnabled = ipProps.GetIPv4Properties()?.IsDhcpEnabled ?? false
};
}
| 平台 | NetworkInformation | System.Management (WMI) |
|---|---|---|
| Windows | ✅ 完整支援 | ✅ 完整支援 |
| Linux | ✅ 核心功能支援 | ❌ 不支援 |
| macOS | ✅ 核心功能支援 | ❌ 不支援 |
| Docker 容器 | ⚠️ 看宿主機設定 | ❌ 不支援 |
跨平台專案請優先使用 System.Net.NetworkInformation,WMI 僅作為 Windows 專用補充。
public static string GenerateDeviceFingerprint()
{
var info = NetworkInfo.GetLocalIdentity();
var mac = info.PrimaryMac ?? "NO-MAC";
var hostname = info.HostName ?? "NO-HOST";
// 結合多因子產生指紋,避免單一 MAC 變更導致授權失效
string raw = $"{hostname}|{mac}|{Environment.MachineName}|{Environment.ProcessorCount}";
using (var sha = System.Security.Cryptography.SHA256.Create())
{
byte[] hash = sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes(raw));
return Convert.ToBase64String(hash)[..24]; // 取前 24 字元
}
}
使用 NetworkInterface.GetAllNetworkInterfaces() 為現代跨平台首選,搭配 LINQ 過濾虛擬介面。授權綁定建議採用多因子指紋而非單一 MAC,提高彈性與安全性。