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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/218284/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 10:22:18  来源:igfitidea点击:

Read MAC Address from network adapter in .NET

.netethernetmac-address

提问by Stu Mackellar

I'd like to be able to read the mac address from the first active network adapter using VB.net or C# (using .NET 3.5 SP1) for a winform application

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

回答by Stu Mackellar

Since .Net 2.0 there's been a NetworkInterface class in the System.Net.NetworkInformation namespace that will give you this information. Try this:

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

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

回答by Ilya Kochetov

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

来自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

I am sure you'll have no trouble porting this code to C# if you need to

如果您需要,我相信您可以毫无困难地将此代码移植到 C#

回答by Andrew

using Linq..

using System.Net.NetworkInformation;
..

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

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

回答by plinth

Here's a class to do that:

这是一个可以做到这一点的课程:

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);
    }
}

And here's some test code:

这是一些测试代码:

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

I'm sure the ToString method could be better, but it does the job.

我确信 ToString 方法可能会更好,但它可以胜任。

回答by Lou Franco

You need to DllImport GetAdaptersInfo -- here's some C# code

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

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

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

回答by charlitos1mx

It looks like this is an old post but I know that you will run into this thread looking for help so here is what I did today to get the MAC addresses of all the network interfaces in my Laptop.

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

First of all you have to import the following

首先,您必须导入以下内容

Imports System.Net.NetworkInformation

This is the function that returns all the MAC addresses in an string array

这是返回字符串数组中所有 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

回答by AlainD

For anyone using the more limited Compact Framework (.NET v2.0 CF) the following code works on both Windows CE 5.0 and CE 6.0 (reading just the adaptor name, but search for "typedef struct _IP_ADAPTER_INFO" on MSDN to get the full definition of the structure returned):

对于使用更有限的 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";
    }
}