无论使用C#运行的操作系统如何,我都需要一种获取机器MAC地址的方法.应用程序需要在XP/Vista/Win7 32和64位以及这些操作系统上运行,但具有外语默认值.许多C#命令和OS查询不能在OS上运行.有任何想法吗?我一直在抓取"ipconfig/all"的输出,但这非常不可靠,因为每台机器的输出格式都不同.
谢谢
更清洁的解决方案
var macAddr = ( from nic in NetworkInterface.GetAllNetworkInterfaces() where nic.OperationalStatus == OperationalStatus.Up select nic.GetPhysicalAddress().ToString() ).FirstOrDefault();
要么:
String firstMacAddress = NetworkInterface .GetAllNetworkInterfaces() .Where( nic => nic.OperationalStatus == OperationalStatus.Up && nic.NetworkInterfaceType != NetworkInterfaceType.Loopback ) .Select( nic => nic.GetPhysicalAddress().ToString() ) .FirstOrDefault();
这是一些C#代码,它返回第一个可操作网络接口的MAC地址.假设NetworkInterface
程序集是在其他操作系统上使用的运行时(即Mono)中实现的,那么这将适用于其他操作系统.
新版本:以最快的速度返回NIC,该速度也具有有效的MAC地址.
////// Finds the MAC address of the NIC with maximum speed. /// ///The MAC address. private string GetMacAddress() { const int MIN_MAC_ADDR_LENGTH = 12; string macAddress = string.Empty; long maxSpeed = -1; foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces()) { log.Debug( "Found MAC Address: " + nic.GetPhysicalAddress() + " Type: " + nic.NetworkInterfaceType); string tempMac = nic.GetPhysicalAddress().ToString(); if (nic.Speed > maxSpeed && !string.IsNullOrEmpty(tempMac) && tempMac.Length >= MIN_MAC_ADDR_LENGTH) { log.Debug("New Max Speed = " + nic.Speed + ", MAC: " + tempMac); maxSpeed = nic.Speed; macAddress = tempMac; } } return macAddress; }
原始版本:只返回第一个.
////// Finds the MAC address of the first operation NIC found. /// ///The MAC address. private string GetMacAddress() { string macAddresses = string.Empty; foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces()) { if (nic.OperationalStatus == OperationalStatus.Up) { macAddresses += nic.GetPhysicalAddress().ToString(); break; } } return macAddresses; }
我不喜欢这种方法的唯一方法是,如果您喜欢Nortel Packet Miniport或某种类型的VPN连接,它有可能被选中.据我所知,没有办法区分实际物理设备的MAC与某种类型的虚拟网络接口.
Win32_NetworkAdapterConfiguration WMI类的MACAddress属性可以为您提供适配器的MAC地址.(System.Management命名空间)
MACAddress Data type: string Access type: Read-only Media Access Control (MAC) address of the network adapter. A MAC address is assigned by the manufacturer to uniquely identify the network adapter. Example: "00:80:C7:8F:6C:96"
如果您不熟悉WMI API(Windows Management Instrumentation),那么.NET应用程序的概述很好.
使用.Net运行时,所有版本的Windows都可以使用WMI.
这是一个代码示例:
System.Management.ManagementClass mc = default(System.Management.ManagementClass); ManagementObject mo = default(ManagementObject); mc = new ManagementClass("Win32_NetworkAdapterConfiguration"); ManagementObjectCollection moc = mc.GetInstances(); foreach (var mo in moc) { if (mo.Item("IPEnabled") == true) { Adapter.Items.Add("MAC " + mo.Item("MacAddress").ToString()); } }
如果您连接的计算机是Windows计算机,WMI是最佳解决方案,但如果您正在查看Linux,Mac或其他类型的网络适配器,那么您将需要使用其他东西.以下是一些选项:
使用DOS命令nbtstat -a.创建一个进程,调用此命令,解析输出.
首先Ping IP以确保您的NIC在其ARP表中缓存该命令,然后使用DOS命令arp -a.像选项1一样解析过程的输出.
在iphlpapi.dll中使用可怕的非托管调用sendarp
下面是项目#3的样本.如果WMI不是一个可行的解决方案,这似乎是最好的选择:
using System.Runtime.InteropServices; ... [DllImport("iphlpapi.dll", ExactSpelling = true)] public static extern int SendARP(int DestIP, int SrcIP, byte[] pMacAddr, ref uint PhyAddrLen); ... private string GetMacUsingARP(string IPAddr) { IPAddress IP = IPAddress.Parse(IPAddr); byte[] macAddr = new byte[6]; uint macAddrLen = (uint)macAddr.Length; if (SendARP((int)IP.Address, 0, macAddr, ref macAddrLen) != 0) throw new Exception("ARP command failed"); string[] str = new string[(int)macAddrLen]; for (int i = 0; i < macAddrLen; i++) str[i] = macAddr[i].ToString("x2"); return string.Join(":", str); }
为了给予应有的信用,这是该代码的基础:http: //www.pinvoke.net/default.aspx/iphlpapi.sendarp#
我们使用WMI来获取具有最低度量的接口的mac地址,例如接口窗口将更喜欢使用,如下所示:
public static string GetMACAddress() { ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration where IPEnabled=true"); IEnumerableobjects = searcher.Get().Cast (); string mac = (from o in objects orderby o["IPConnectionMetric"] select o["MACAddress"].ToString()).FirstOrDefault(); return mac; }
或者在Silverlight中(需要提升信任度):
public static string GetMACAddress() { string mac = null; if ((Application.Current.IsRunningOutOfBrowser) && (Application.Current.HasElevatedPermissions) && (AutomationFactory.IsAvailable)) { dynamic sWbemLocator = AutomationFactory.CreateObject("WbemScripting.SWBemLocator"); dynamic sWbemServices = sWbemLocator.ConnectServer("."); sWbemServices.Security_.ImpersonationLevel = 3; //impersonate string query = "SELECT * FROM Win32_NetworkAdapterConfiguration where IPEnabled=true"; dynamic results = sWbemServices.ExecQuery(query); int mtu = int.MaxValue; foreach (dynamic result in results) { if (result.IPConnectionMetric < mtu) { mtu = result.IPConnectionMetric; mac = result.MACAddress; } } } return mac; }
public static PhysicalAddress GetMacAddress() { var myInterfaceAddress = NetworkInterface.GetAllNetworkInterfaces() .Where(n => n.OperationalStatus == OperationalStatus.Up && n.NetworkInterfaceType != NetworkInterfaceType.Loopback) .OrderByDescending(n => n.NetworkInterfaceType == NetworkInterfaceType.Ethernet) .Select(n => n.GetPhysicalAddress()) .FirstOrDefault(); return myInterfaceAddress; }
我需要获取用于连接到互联网的实际NIC的MAC; 确定在我的客户端应用程序中使用哪个WCF接口.
我在这里看到很多答案,但没有一个能帮助我.希望这个答案可以帮助一些人.
此解决方案返回用于连接到Internet的NIC的MAC.
private static PhysicalAddress GetCurrentMAC(string allowedURL) { TcpClient client = new TcpClient(); client.Client.Connect(new IPEndPoint(Dns.GetHostAddresses(allowedURL)[0], 80)); while(!client.Connected) { Thread.Sleep(500); } IPAddress address2 = ((IPEndPoint)client.Client.LocalEndPoint).Address; client.Client.Disconnect(false); NetworkInterface[] allNetworkInterfaces = NetworkInterface.GetAllNetworkInterfaces(); client.Close(); if(allNetworkInterfaces.Length > 0) { foreach(NetworkInterface interface2 in allNetworkInterfaces) { UnicastIPAddressInformationCollection unicastAddresses = interface2.GetIPProperties().UnicastAddresses; if((unicastAddresses != null) && (unicastAddresses.Count > 0)) { for(int i = 0; i < unicastAddresses.Count; i++) if(unicastAddresses[i].Address.Equals(address2)) return interface2.GetPhysicalAddress(); } } } return null; }
要调用它,您需要传递一个URL来连接到这样:
PhysicalAddress mac = GetCurrentMAC("www.google.com");