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

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

【问题讨论】:

    标签: .net ethernet mac-address


    【解决方案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 - 在我发布实际代码之前,您应该与我确认一下! -史蒂夫
            猜你喜欢
            • 2012-07-06
            • 1970-01-01
            • 1970-01-01
            • 2010-09-18
            • 2023-04-08
            • 1970-01-01
            • 2012-09-29
            • 2014-09-22
            相关资源
            最近更新 更多