从 .NET 中的网络适配器读取 MAC 地址

Posted

技术标签:

【中文标题】从 .NET 中的网络适配器读取 MAC 地址【英文标题】:Read MAC Address from network adapter in .NET 【发布时间】:2010-09-18 02:40:56 【问题描述】:

我希望能够为 winform 应用程序使用 VB.net 或 C#(使用 .NET 3.5 SP1)从第一个活动网络适配器读取 mac 地址

【问题讨论】:

【参考方案1】:

对于使用更有限的 Compact Framework (.NET v2.0 CF) 的任何人,以下代码适用于 Windows CE 5.0 和 CE 6.0(仅读取适配器名称,但在 MSDN 上搜索“typedef struct _IP_ADAPTER_INFO”以获取返回的结构的完整定义):

private const int MAX_ADAPTER_NAME_LENGTH = 256;
[DllImport ("iphlpapi.dll", SetLastError = true)]
private static extern int GetAdaptersInfo(byte[] abyAdaptor, ref int nSize);

// ...
private static string m_szAdaptorName = "DM9CE1";

// ...
private void GetNetworkAdaptorName()

    // The initial call is to determine the size of the memory required. This will fail
    // with the error code "111" which is defined by MSDN to be "ERROR_BUFFER_OVERFLOW".
    // The structure size should be 640 bytes per adaptor.
    int nSize = 0;
    int nReturn = GetAdaptersInfo(null, ref nSize);

    // Allocate memory and get data
    byte[] abyAdapatorInfo = new byte[nSize];
    nReturn = GetAdaptersInfo(abyAdapatorInfo, ref nSize);
    if (nReturn == 0)
    
        // Find the start and end bytes of the name in the returned structure
        int nStartNamePos = 8;
        int nEndNamePos = 8;
        while ((abyAdapatorInfo[nEndNamePos] != 0) &&
                    ((nEndNamePos - nStartNamePos) < MAX_ADAPTER_NAME_LENGTH))
        
            // Another character in the name
            nEndNamePos++;
        

        // Convert the name from a byte array into a string
        m_szAdaptorName = Encoding.UTF8.GetString(
            abyAdapatorInfo, nStartNamePos, (nEndNamePos - nStartNamePos));
    
    else
    
        // Failed? Use a hard-coded network adaptor name.
        m_szAdaptorName = "DM9CE1";
    

【讨论】:

【参考方案2】:

看起来这是一篇旧帖子,但我知道您会遇到此线程寻求帮助,所以这就是我今天所做的,以获取笔记本电脑中所有网络接口的 MAC 地址。

首先你要导入以下内容

Imports System.Net.NetworkInformation

这是返回字符串数组中所有 MAC 地址的函数

Private Function GetMAC() As String()
    Dim MACAddresses(0) As String
    Dim i As Integer = 0
    Dim NIC As NetworkInterface

    For Each NIC In NetworkInterface.GetAllNetworkInterfaces
        ReDim Preserve MACAddresses(i)
        MACAddresses(i) = String.Format("0", NIC.GetPhysicalAddress())
        i += 1
    Next
    Return MACAddresses
End Function

【讨论】:

【参考方案3】:
using Linq..

using System.Net.NetworkInformation;
..

NetworkInterface nic =
    NetworkInterface.GetAllNetworkInterfaces()
    .Where(n => n.OperationalStatus == OperationalStatus.Up).FirstOrDefault();

if (nic != null)
    return nic.GetPhysicalAddress().ToString();

【讨论】:

【参考方案4】:

从 .Net 2.0 开始,System.Net.NetworkInformation 命名空间中有一个 NetworkInterface 类可以为您提供这些信息。试试这个:

        foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
        
            if (nic.OperationalStatus == OperationalStatus.Up)
            
                Console.WriteLine(nic.GetPhysicalAddress().ToString());
                break;
            
        

【讨论】:

效果很好。只需更改 if (nic.OperationalStatus == OperationalStatus.Up) 当安装 virtualbox 或有两个以上的适配器启动时,然后获取第一个适配器。【参考方案5】:

这是一个可以做到这一点的类:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace MacAddress

    class MacAddress
    
        byte[] _address;

        public MacAddress(byte[] b)
        
            if (b == null)
                throw new ArgumentNullException("b");
            if (b.Length != 8)
                throw new ArgumentOutOfRangeException("b");
            _address = new byte[b.Length];
            Array.Copy(b, _address, b.Length);
        

        public byte[] Address  get  return _address;  

        public override string ToString()
        
            return Address[0].ToString("X2", System.Globalization.CultureInfo.InvariantCulture) + ":" +
                    Address[1].ToString("X2", System.Globalization.CultureInfo.InvariantCulture) + ":" +
                    Address[2].ToString("X2", System.Globalization.CultureInfo.InvariantCulture) + ":" +
                    Address[3].ToString("X2", System.Globalization.CultureInfo.InvariantCulture) + ":" +
                    Address[4].ToString("X2", System.Globalization.CultureInfo.InvariantCulture) + ":" +
                    Address[5].ToString("X2", System.Globalization.CultureInfo.InvariantCulture);
        

        public static List<MacAddress> GetMacAddresses()
        
            int size = 0;
            // this chunk of code teases out the first adapter info
            int r = GetAdaptersInfo(null, ref size);
            if ((r != IPConfigConst.ERROR_SUCCESS) && (r != IPConfigConst.ERROR_BUFFER_OVERFLOW))
            
                return null;
            
            Byte[] buffer = new Byte[size];
            r = GetAdaptersInfo(buffer, ref size);
            if (r != IPConfigConst.ERROR_SUCCESS)
            
                return null;
            
            AdapterInfo Adapter = new AdapterInfo();
            ByteArray_To_IPAdapterInfo(ref Adapter, buffer, Marshal.SizeOf(Adapter));

            List<MacAddress> addresses = new List<MacAddress>();
            do
            
                addresses.Add(new MacAddress(Adapter.Address));
                IntPtr p = Adapter.NextPointer;
                if (p != IntPtr.Zero)
                
                    IntPtr_To_IPAdapterInfo(ref Adapter, p, Marshal.SizeOf(Adapter));
                
                else
                
                    break;
                
             while (true);
            return addresses;
        

        // glue definitions into windows
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        private struct IPAddrString
        
            public IntPtr NextPointer;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4 * 4)]
            public String IPAddressString;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4 * 4)]
            public String IPMaskString;
            public int Context;
        

        private class IPConfigConst
        
            public const int MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
            public const int MAX_ADAPTER_NAME_LENGTH = 256;
            public const int MAX_ADAPTER_ADDRESS_LENGTH = 8;
            public const int ERROR_BUFFER_OVERFLOW = 111;
            public const int ERROR_SUCCESS = 0;
        

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        private struct AdapterInfo
        
            public IntPtr NextPointer;
            public int ComboIndex;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = IPConfigConst.MAX_ADAPTER_NAME_LENGTH + 4)]
            public string AdapterName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = IPConfigConst.MAX_ADAPTER_DESCRIPTION_LENGTH + 4)]
            public string Description;
            public int AddressLength;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = IPConfigConst.MAX_ADAPTER_ADDRESS_LENGTH)]
            public Byte[] Address;
            public int Index;
            public int Type;
            public int DhcpEnabled;
            public IntPtr CurrentIPAddress;
            public IPAddrString IPAddressList;
            public IPAddrString GatewayList;
            public IPAddrString DhcpServer;
            public Boolean HaveWins;
            public IPAddrString PrimaryWinsServer;
            public IPAddrString SecondaryWinsServer;
            public int LeaseObtained;
            public int LeaseExpires;
        
        [DllImport("Iphlpapi.dll", CharSet = CharSet.Auto)]
        private static extern int GetAdaptersInfo(Byte[] PAdapterInfoBuffer, ref int size);
        [DllImport("Kernel32.dll", EntryPoint = "CopyMemory")]
        private static extern void ByteArray_To_IPAdapterInfo(ref AdapterInfo dst, Byte[] src, int size);
        [DllImport("Kernel32.dll", EntryPoint = "CopyMemory")]
        private static extern void IntPtr_To_IPAdapterInfo(ref AdapterInfo dst, IntPtr src, int size);
    

下面是一些测试代码:

        List<MacAddress> addresses = MacAddress.GetMacAddresses();
        foreach (MacAddress address in addresses)
        
            Console.WriteLine(address);
        

我确信 ToString 方法可能会更好,但它确实有效。

【讨论】:

【参考方案6】:

来自http://www.dotnetjunkies.com/WebLog/jkirwan/archive/2004/02/10/6943.aspx

  Dim mc As System.Management.ManagementClass
  Dim mo As ManagementObject
  mc = New ManagementClass("Win32_NetworkAdapterConfiguration")
  Dim moc As ManagementObjectCollection = mc.GetInstances()
  For Each mo In moc
     If mo.Item("IPEnabled") = True Then
        ListBox1.Items.Add("MAC address " & mo.Item("MacAddress").ToString())
     End If
  Next

如果您需要,我相信您可以轻松将此代码移植到 C# 中

【讨论】:

如果运行此代码的笔记本禁用了网络适配器会怎样?【参考方案7】:

您需要 DllImport GetAdaptersInfo -- 这是一些 C# 代码

http://www.codeguru.com/cpp/i-n/network/networkinformation/comments.php/c5451/?thread=60212

【讨论】:

嘿 Lou - 在我发布实际代码之前,您应该与我确认一下! -史蒂夫

以上是关于从 .NET 中的网络适配器读取 MAC 地址的主要内容,如果未能解决你的问题,请参考以下文章

网络 - 如何查看物理(MAC)地址?

在Android机顶盒上 怎样获取有线网卡MAC地址?

电脑mac地址查询方法

mac地址怎么查

C++:在 Vista 上获取网络适配器的 MAC 地址?

如何获取当前使用的网络适配器