无论使用C#运行的操作系统如何,我都需要一种获取机器MAC地址的方法。应用程序需要在XP / Vista / Win7 32和64位以及这些操作系统上运行,但具有外语默认值。许多C#命令和OS查询不能在OS上运行。有任何想法吗?我一直在抓取“ipconfig / all”的输出,但这非常不可靠,因为每台机器的输出格式都不同。
由于
答案 0 :(得分:116)
清洁解决方案
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();
答案 1 :(得分:76)
这是一些C#代码,它返回第一个可操作网络接口的MAC地址。假设NetworkInterface
程序集在其他操作系统上使用的运行时(即Mono)中实现,那么这将适用于其他操作系统。
新版本:以最快的速度返回网卡,也具有有效的MAC地址。
/// <summary>
/// Finds the MAC address of the NIC with maximum speed.
/// </summary>
/// <returns>The MAC address.</returns>
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;
}
原始版本:只返回第一个。
/// <summary>
/// Finds the MAC address of the first operation NIC found.
/// </summary>
/// <returns>The MAC address.</returns>
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与某种类型的虚拟网络接口。
答案 2 :(得分:10)
如果您连接的计算机是Windows计算机,WMI是最佳解决方案,但如果您正在查看Linux,Mac或其他类型的网络适配器,那么您将需要使用其他内容。以下是一些选项:
下面是第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#
答案 3 :(得分:10)
Win32_NetworkAdapterConfiguration WMI class的 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应用程序就有good overview here。
WMI适用于.Net运行时的所有版本的Windows。
这是一个代码示例:
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());
}
}
答案 4 :(得分:7)
我们使用WMI获取具有最低指标的接口的mac地址,例如接口窗口将更喜欢使用,如下所示:
public static string GetMACAddress()
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration where IPEnabled=true");
IEnumerable<ManagementObject> objects = searcher.Get().Cast<ManagementObject>();
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;
}
答案 5 :(得分:6)
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;
}
答案 6 :(得分:5)
我需要获取用于连接到互联网的实际NIC的MAC;确定在我的客户端应用程序中使用哪个WCF接口。
我在这里看到很多答案,但没有一个能帮助我。希望这个答案有所帮助。
此解决方案返回用于连接到互联网的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");
答案 7 :(得分:4)
您可以使用NIC ID:
foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces()) {
if (nic.OperationalStatus == OperationalStatus.Up){
if (nic.Id == "yay!")
}
}
这不是MAC地址,但它是一个唯一的标识符,如果这是你正在寻找的。
答案 8 :(得分:4)
恕我直言,返回第一个mac地址不是一个好主意,尤其是在托管虚拟机时。因此,我检查了发送/接收的字节总和并选择了最常用的连接,虽然这并不完美,但应该正确9/10次。
public string GetDefaultMacAddress()
{
Dictionary<string, long> macAddresses = new Dictionary<string, long>();
foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
{
if (nic.OperationalStatus == OperationalStatus.Up)
macAddresses[nic.GetPhysicalAddress().ToString()] = nic.GetIPStatistics().BytesSent + nic.GetIPStatistics().BytesReceived;
}
long maxValue = 0;
string mac = "";
foreach(KeyValuePair<string, long> pair in macAddresses)
{
if (pair.Value > maxValue)
{
mac = pair.Key;
maxValue = pair.Value;
}
}
return mac;
}
答案 9 :(得分:2)
假设我使用我的本地IP 192.168.0.182进行TcpConnection。然后,如果我想知道该NIC的mac地址,我将调用meothod:GetMacAddressUsedByIp("192.168.0.182")
public static string GetMacAddressUsedByIp(string ipAddress)
{
var ips = new List<string>();
string output;
try
{
// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.FileName = "ipconfig";
p.StartInfo.Arguments = "/all";
p.Start();
// Do not wait for the child process to exit before
// reading to the end of its redirected stream.
// p.WaitForExit();
// Read the output stream first and then wait.
output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
}
catch
{
return null;
}
// pattern to get all connections
var pattern = @"(?xis)
(?<Header>
(\r|\n) [^\r]+ : \r\n\r\n
)
(?<content>
.+? (?= ( (\r\n\r\n)|($)) )
)";
List<Match> matches = new List<Match>();
foreach (Match m in Regex.Matches(output, pattern))
matches.Add(m);
var connection = matches.Select(m => new
{
containsIp = m.Value.Contains(ipAddress),
containsPhysicalAddress = Regex.Match(m.Value, @"(?ix)Physical \s Address").Success,
content = m.Value
}).Where(x => x.containsIp && x.containsPhysicalAddress)
.Select(m => Regex.Match(m.content, @"(?ix) Physical \s address [^:]+ : \s* (?<Mac>[^\s]+)").Groups["Mac"].Value).FirstOrDefault();
return connection;
}
答案 10 :(得分:2)
真的很讨厌挖掘这个老帖子,但我觉得这个问题值得Windows 8-10特有的另一个答案。
使用NetworkInformation命名空间中的Windows.Networking.Connectivity,您可以获取网络适配器窗口的ID正在使用。然后,您可以从前面提到的GetAllNetworkInterfaces()中获取接口MAC地址。
这在Windows Store应用中不起作用,因为System.Net中的NetworkInterface .NetworkInformation不会公开GetAllNetworkInterfaces。
string GetMacAddress()
{
var connectionProfile = NetworkInformation.GetInternetConnectionProfile();
if (connectionProfile == null) return "";
var inUseId = connectionProfile.NetworkAdapter.NetworkAdapterId.ToString("B").ToUpperInvariant();
if(string.IsNullOrWhiteSpace(inUseId)) return "";
var mac = NetworkInterface.GetAllNetworkInterfaces()
.Where(n => inUseId == n.Id)
.Select(n => n.GetPhysicalAddress().GetAddressBytes().Select(b=>b.ToString("X2")))
.Select(macBytes => string.Join(" ", macBytes))
.FirstOrDefault();
return mac;
}
答案 11 :(得分:2)
我非常喜欢具有最低IP连接指标的AVee解决方案!但是如果安装了具有相同度量的第二个nic,则MAC比较可能会失败......
最好用MAC存储接口的描述。在以后的比较中,您可以通过此字符串识别正确的nic。以下是示例代码:
public static string GetMacAndDescription()
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration where IPEnabled=true");
IEnumerable<ManagementObject> objects = searcher.Get().Cast<ManagementObject>();
string mac = (from o in objects orderby o["IPConnectionMetric"] select o["MACAddress"].ToString()).FirstOrDefault();
string description = (from o in objects orderby o["IPConnectionMetric"] select o["Description"].ToString()).FirstOrDefault();
return mac + ";" + description;
}
public static string GetMacByDescription( string description)
{
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration where IPEnabled=true");
IEnumerable<ManagementObject> objects = searcher.Get().Cast<ManagementObject>();
string mac = (from o in objects where o["Description"].ToString() == description select o["MACAddress"].ToString()).FirstOrDefault();
return mac;
}
答案 12 :(得分:1)
string mac = "";
foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
{
if (nic.OperationalStatus == OperationalStatus.Up && (!nic.Description.Contains("Virtual") && !nic.Description.Contains("Pseudo")))
{
if (nic.GetPhysicalAddress().ToString() != "")
{
mac = nic.GetPhysicalAddress().ToString();
}
}
}
MessageBox.Show(mac);
答案 13 :(得分:1)
foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
{
if (nic.OperationalStatus == OperationalStatus.Up)
{
PhysicalAddress Mac = nic.GetPhysicalAddress();
}
}
答案 14 :(得分:0)
试试这个:
/// <summary>
/// returns the first MAC address from where is executed
/// </summary>
/// <param name="flagUpOnly">if sets returns only the nic on Up status</param>
/// <returns></returns>
public static string[] getOperationalMacAddresses(Boolean flagUpOnly)
{
string[] macAddresses = new string[NetworkInterface.GetAllNetworkInterfaces().Count()];
int i = 0;
foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
{
if (nic.OperationalStatus == OperationalStatus.Up || !flagUpOnly)
{
macAddresses[i] += ByteToHex(nic.GetPhysicalAddress().GetAddressBytes());
//break;
i++;
}
}
return macAddresses;
}
答案 15 :(得分:0)
稍微改变了blak3r他的代码。如果您有两个速度相同的适配器。按MAC排序,因此您总能获得相同的值。
public string GetMacAddress()
{
const int MIN_MAC_ADDR_LENGTH = 12;
string macAddress = string.Empty;
Dictionary<string, long> macPlusSpeed = new Dictionary<string, long>();
try
{
foreach(NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
{
System.Diagnostics.Debug.WriteLine("Found MAC Address: " + nic.GetPhysicalAddress() + " Type: " + nic.NetworkInterfaceType);
string tempMac = nic.GetPhysicalAddress().ToString();
if(!string.IsNullOrEmpty(tempMac) && tempMac.Length >= MIN_MAC_ADDR_LENGTH)
macPlusSpeed.Add(tempMac, nic.Speed);
}
macAddress = macPlusSpeed.OrderByDescending(row => row.Value).ThenBy(row => row.Key).FirstOrDefault().Key;
}
catch{}
System.Diagnostics.Debug.WriteLine("Fastest MAC address: " + macAddress);
return macAddress;
}
答案 16 :(得分:0)
ipconfig.exe
使用各种DLL实现,包括iphlpapi.dll
... Google iphlpapi
的Google搜索显示了MSDN中记录的相应Win32 API。