C#获取MAC地址的几种方法

关于获取本地电脑的MAC地址,除了前面说过的根据WMI获取 http://blog.csdn.net/yysyangyangyangshan/article/details/6803787 ,其实还有好几种方式来获取mac地址,下面一一道来。

首先需要用到的一些方法和类:

[csharp]  view plain  copy
 print ?
  1. public enum NCBCONST  
  2. {  
  3.     NCBNAMSZ = 16,               
  4.     MAX_LANA = 254,              
  5.     NCBENUM = 0x37,              
  6.     NRC_GOODRET = 0x00,          
  7.     NCBRESET = 0x32,             
  8.     NCBASTAT = 0x33,             
  9.     NUM_NAMEBUF = 30,            
  10. }  
  11.   
  12. [StructLayout(LayoutKind.Sequential)]  
  13. public struct ADAPTER_STATUS  
  14. {  
  15.     [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]  
  16.     public byte[] adapter_address;  
  17.     public byte rev_major;  
  18.     public byte reserved0;  
  19.     public byte adapter_type;  
  20.     public byte rev_minor;  
  21.     public ushort duration;  
  22.     public ushort frmr_recv;  
  23.     public ushort frmr_xmit;  
  24.     public ushort iframe_recv_err;  
  25.     public ushort xmit_aborts;  
  26.     public uint xmit_success;  
  27.     public uint recv_success;  
  28.     public ushort iframe_xmit_err;  
  29.     public ushort recv_buff_unavail;  
  30.     public ushort t1_timeouts;  
  31.     public ushort ti_timeouts;  
  32.     public uint reserved1;  
  33.     public ushort free_ncbs;  
  34.     public ushort max_cfg_ncbs;  
  35.     public ushort max_ncbs;  
  36.     public ushort xmit_buf_unavail;  
  37.     public ushort max_dgram_size;  
  38.     public ushort pending_sess;  
  39.     public ushort max_cfg_sess;  
  40.     public ushort max_sess;  
  41.     public ushort max_sess_pkt_size;  
  42.     public ushort name_count;  
  43. }  
  44.   
  45. [StructLayout(LayoutKind.Sequential)]  
  46. public struct NAME_BUFFER  
  47. {  
  48.     [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NCBCONST.NCBNAMSZ)]  
  49.     public byte[] name;  
  50.     public byte name_num;  
  51.     public byte name_flags;  
  52. }  
  53.   
  54. [StructLayout(LayoutKind.Sequential)]  
  55. public struct NCB  
  56. {  
  57.     public byte ncb_command;  
  58.     public byte ncb_retcode;  
  59.     public byte ncb_lsn;  
  60.     public byte ncb_num;  
  61.     public IntPtr ncb_buffer;  
  62.     public ushort ncb_length;  
  63.     [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NCBCONST.NCBNAMSZ)]  
  64.     public byte[] ncb_callname;  
  65.     [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NCBCONST.NCBNAMSZ)]  
  66.     public byte[] ncb_name;  
  67.     public byte ncb_rto;  
  68.     public byte ncb_sto;  
  69.     public IntPtr ncb_post;  
  70.     public byte ncb_lana_num;  
  71.     public byte ncb_cmd_cplt;  
  72.     [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]  
  73.     public byte[] ncb_reserve;  
  74.     public IntPtr ncb_event;  
  75. }  
  76.   
  77. [StructLayout(LayoutKind.Sequential)]  
  78. public struct LANA_ENUM  
  79. {  
  80.     public byte length;  
  81.     [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NCBCONST.MAX_LANA)]  
  82.     public byte[] lana;  
  83. }  
  84.   
  85. [StructLayout(LayoutKind.Auto)]  
  86. public struct ASTAT  
  87. {  
  88.     public ADAPTER_STATUS adapt;  
  89.     [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)NCBCONST.NUM_NAMEBUF)]  
  90.     public NAME_BUFFER[] NameBuff;  
  91. }  
  92. public class Win32API  
  93. {  
  94.     [DllImport("NETAPI32.DLL")]  
  95.     public static extern char Netbios(ref   NCB ncb);  
  96. }  
  97.   
  98. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]  
  99. public class IP_Adapter_Addresses  
  100. {  
  101.     public uint Length;  
  102.     public uint IfIndex;  
  103.     public IntPtr Next;  
  104.   
  105.     public IntPtr AdapterName;  
  106.     public IntPtr FirstUnicastAddress;  
  107.     public IntPtr FirstAnycastAddress;  
  108.     public IntPtr FirstMulticastAddress;  
  109.     public IntPtr FirstDnsServerAddress;  
  110.   
  111.     public IntPtr DnsSuffix;  
  112.     public IntPtr Description;  
  113.   
  114.     public IntPtr FriendlyName;  
  115.   
  116.     [MarshalAs(UnmanagedType.ByValArray,  
  117.          SizeConst = 8)]  
  118.     public Byte[] PhysicalAddress;  
  119.   
  120.     public uint PhysicalAddressLength;  
  121.     public uint flags;  
  122.     public uint Mtu;  
  123.     public uint IfType;  
  124.   
  125.     public uint OperStatus;  
  126.   
  127.     public uint Ipv6IfIndex;  
  128.     public uint ZoneIndices;  
  129.   
  130.     public IntPtr FirstPrefix;  
  131. }  

1、  SendArp 获取MAC地址

SendARP函数用来发送ARP数据包并在定义的MAC缓冲区中返回定义的IP对应的MAC地址

SendARP(

    IPAddr DestIP,

    IPAddr SrcIP,

    PULONG pMacAddr,

    PULONG PhyAddrLen

    );

第一个参数是IP地址的网络字节顺序,而不是一个指针,当初我就是赋值成指针而使得获取不了MAC地址。

第二个参数填0就可以

第三个参数是MAC缓冲区指针

第四个参数是一个指向一个DWORD型数值为6的指针

代码如下:

[csharp]  view plain  copy
 print ?
  1. [DllImport("Iphlpapi.dll")]  
  2. static extern int SendARP(Int32 DestIP, Int32 SrcIP, ref Int64 MacAddr, ref Int32 PhyAddrLen);  
  3. /// <summary>  
  4. /// SendArp获取MAC地址  
  5. /// </summary>  
  6. /// <returns></returns>  
  7. public string GetMacAddressBySendARP()  
  8. {  
  9.     StringBuilder strReturn = new StringBuilder();  
  10.     try  
  11.     {  
  12.         System.Net.IPHostEntry Tempaddr = (System.Net.IPHostEntry)Dns.GetHostByName(Dns.GetHostName());  
  13.         System.Net.IPAddress[] TempAd = Tempaddr.AddressList;  
  14.         Int32 remote = (int)TempAd[0].Address;  
  15.         Int64 macinfo = new Int64();  
  16.         Int32 length = 6;  
  17.         SendARP(remote, 0, ref macinfo, ref length);  
  18.   
  19.         string temp = System.Convert.ToString(macinfo, 16).PadLeft(12, '0').ToUpper();  
  20.   
  21.         int x = 12;  
  22.         for (int i = 0; i < 6; i++)  
  23.         {  
  24.             if (i == 5) { strReturn.Append(temp.Substring(x - 2, 2)); }  
  25.             else { strReturn.Append(temp.Substring(x - 2, 2) + ":"); }  
  26.             x -= 2;  
  27.         }  
  28.   
  29.         return strReturn.ToString();  
  30.     }  
  31.     catch  
  32.     {  
  33.         return "";  
  34.     }  
  35. }  

2、通过适配器信息获取MAC地址

iphlpapi.dll是Windows IP辅助API应用程序接口模块。其中一个函数GetAdaptersAddresses:返回和适配器关联的地址

uint GetAdaptersAddresses(uint Family, uint flags, IntPtr Reserved,

            IntPtr PAdaptersAddresses, ref uint pOutBufLen);

Family:[输入]获得地址族,必须是以下值之一:

AF_INET (仅返回IPv4地址),

       AF_INET6(仅返回IPv6地址),

       AF_UNSPEC(从所有的地址族返回地址)

Flags:[输入]返回地址类型,这个参数为0或是以下值的联合值:

GAA_FLAG_INCLUDE_PREFIX (返回IPv6地址前缀)

GAA_FLAG_SKIP_UNICAST(不返回unicast地址)

GAA_FLAG_SKIP_ANYCAST(不返回anycast地址)

GAA_FLAG_SKIP_FRIENDLY_NAME(不返回适配器的友好名称)

GAA_FLAG_SKIP_MULTICAST (不返回多点传送(multicast)地址)

GAA_FLAG_SKIP_DNS_SERVER (不返回DNS服务器地址)

Reserved:调用程序必须将此参数置为NULL

pAdapterAddresses:[输入,输出] 指向一段IP_ADAPTER_ADDRESSES缓存,成功的话,该缓存包含地址信息。

pOutBufLen:[输出] 返回pAdapterAddresses所在缓存的大小

返回值:成功,返回0;失败,返回错误代码。

代码如下:

[csharp]  view plain  copy
 print ?
  1. [DllImport("Iphlpapi.dll")]  
  2. public static extern uint GetAdaptersAddresses(uint Family, uint flags, IntPtr Reserved,  
  3.     IntPtr PAdaptersAddresses, ref uint pOutBufLen);  
  4.   
  5. /// <summary>  
  6. /// 通过适配器信息获取MAC地址  
  7. /// </summary>  
  8. /// <returns></returns>  
  9. public string GetMacAddressByAdapter()  
  10. {  
  11.     string macAddress = "";  
  12.     try  
  13.     {  
  14.         IntPtr PAdaptersAddresses = new IntPtr();  
  15.   
  16.         uint pOutLen = 100;  
  17.         PAdaptersAddresses = Marshal.AllocHGlobal(100);  
  18.   
  19.         uint ret =  
  20.             GetAdaptersAddresses(0, 0, (IntPtr)0, PAdaptersAddresses, ref pOutLen);  
  21.   
  22.         if (ret == 111)  
  23.         {  
  24.             Marshal.FreeHGlobal(PAdaptersAddresses);  
  25.             PAdaptersAddresses = Marshal.AllocHGlobal((int)pOutLen);  
  26.             ret = GetAdaptersAddresses(0, 0, (IntPtr)0, PAdaptersAddresses, ref pOutLen);  
  27.         }  
  28.   
  29.         IP_Adapter_Addresses adds = new IP_Adapter_Addresses();  
  30.   
  31.         IntPtr pTemp = PAdaptersAddresses;  
  32.   
  33.         while (pTemp != (IntPtr)0)  
  34.         {  
  35.             Marshal.PtrToStructure(pTemp, adds);  
  36.             string adapterName = Marshal.PtrToStringAnsi(adds.AdapterName);  
  37.             string FriendlyName = Marshal.PtrToStringAuto(adds.FriendlyName);  
  38.             string tmpString = string.Empty;  
  39.   
  40.             for (int i = 0; i < 6; i++)  
  41.             {  
  42.                 tmpString += string.Format("{0:X2}", adds.PhysicalAddress[i]);  
  43.   
  44.                 if (i < 5)  
  45.                 {  
  46.                     tmpString += ":";  
  47.                 }  
  48.             }  
  49.   
  50.   
  51.             RegistryKey theLocalMachine = Registry.LocalMachine;  
  52.   
  53.             RegistryKey theSystem  
  54.                 = theLocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces");  
  55.             RegistryKey theInterfaceKey = theSystem.OpenSubKey(adapterName);  
  56.   
  57.             if (theInterfaceKey != null)  
  58.             {  
  59.                 macAddress = tmpString;  
  60.                 break;  
  61.             }  
  62.   
  63.             pTemp = adds.Next;  
  64.         }  
  65.     }  
  66.     catch   
  67.     { }  
  68.     return macAddress;  
  69. }  

3、 通过NetBios获取MAC地址

NetBIOS(网络基本输入/输出系统)是一套用于网络通讯的调用接口,包含NetBIOS Name和MAC地址等信息。该方法获取MAC地址的效率较高。

代码如下:

[csharp]  view plain  copy
 print ?
  1. /// <summary>  
  2. /// 通过NetBios获取MAC地址  
  3. /// </summary>  
  4. /// <returns></returns>  
  5. public string GetMacAddressByNetBios()  
  6. {  
  7.     string macAddress = "";  
  8.     try  
  9.     {  
  10.         string addr = "";  
  11.         int cb;  
  12.         ASTAT adapter;  
  13.         NCB Ncb = new NCB();  
  14.         char uRetCode;  
  15.         LANA_ENUM lenum;  
  16.   
  17.         Ncb.ncb_command = (byte)NCBCONST.NCBENUM;  
  18.         cb = Marshal.SizeOf(typeof(LANA_ENUM));  
  19.         Ncb.ncb_buffer = Marshal.AllocHGlobal(cb);  
  20.         Ncb.ncb_length = (ushort)cb;  
  21.         uRetCode = Win32API.Netbios(ref   Ncb);  
  22.         lenum = (LANA_ENUM)Marshal.PtrToStructure(Ncb.ncb_buffer, typeof(LANA_ENUM));  
  23.         Marshal.FreeHGlobal(Ncb.ncb_buffer);  
  24.         if (uRetCode != (short)NCBCONST.NRC_GOODRET)  
  25.             return "";  
  26.   
  27.         for (int i = 0; i < lenum.length; i++)  
  28.         {  
  29.             Ncb.ncb_command = (byte)NCBCONST.NCBRESET;  
  30.             Ncb.ncb_lana_num = lenum.lana[i];  
  31.             uRetCode = Win32API.Netbios(ref   Ncb);  
  32.             if (uRetCode != (short)NCBCONST.NRC_GOODRET)  
  33.                 return "";  
  34.   
  35.             Ncb.ncb_command = (byte)NCBCONST.NCBASTAT;  
  36.             Ncb.ncb_lana_num = lenum.lana[i];  
  37.             Ncb.ncb_callname[0] = (byte)'*';  
  38.             cb = Marshal.SizeOf(typeof(ADAPTER_STATUS)) + Marshal.SizeOf(typeof(NAME_BUFFER)) * (int)NCBCONST.NUM_NAMEBUF;  
  39.             Ncb.ncb_buffer = Marshal.AllocHGlobal(cb);  
  40.             Ncb.ncb_length = (ushort)cb;  
  41.             uRetCode = Win32API.Netbios(ref   Ncb);  
  42.             adapter.adapt = (ADAPTER_STATUS)Marshal.PtrToStructure(Ncb.ncb_buffer, typeof(ADAPTER_STATUS));  
  43.             Marshal.FreeHGlobal(Ncb.ncb_buffer);  
  44.   
  45.             if (uRetCode == (short)NCBCONST.NRC_GOODRET)  
  46.             {  
  47.                 if (i > 0)  
  48.                     addr += ":";  
  49.                 addr = string.Format("{0,2:X}:{1,2:X}:{2,2:X}:{3,2:X}:{4,2:X}:{5,2:X}",  
  50.                       adapter.adapt.adapter_address[0],  
  51.                       adapter.adapt.adapter_address[1],  
  52.                       adapter.adapt.adapter_address[2],  
  53.                       adapter.adapt.adapter_address[3],  
  54.                       adapter.adapt.adapter_address[4],  
  55.                       adapter.adapt.adapter_address[5]);  
  56.             }  
  57.         }  
  58.         macAddress = addr.Replace(' ''0');  
  59.   
  60.     }  
  61.     catch  
  62.     {  
  63.     }  
  64.     return macAddress;  
  65. }  

4、 通过DOS命令获得MAC地址

这个就是使用ipconfig命令,并需要在程序中启用cmd,程序中使用cmd如下即可,或参见http://blog.csdn.net/yysyangyangyangshan/article/details/6799489,

代码如下:

[csharp]  view plain  copy
 print ?
  1. /// <summary>  
  2. /// 通过DOS命令获得MAC地址  
  3. /// </summary>  
  4. /// <returns></returns>  
  5. public string GetMacAddressByDos()  
  6. {  
  7.     string macAddress = "";  
  8.     Process p = null;  
  9.     StreamReader reader = null;  
  10.     try  
  11.     {  
  12.         ProcessStartInfo start = new ProcessStartInfo("cmd.exe");   
  13.   
  14.         start.FileName = "ipconfig";  
  15.         start.Arguments = "/all";   
  16.   
  17.         start.CreateNoWindow = true;   
  18.   
  19.         start.RedirectStandardOutput = true;   
  20.   
  21.         start.RedirectStandardInput = true;   
  22.   
  23.         start.UseShellExecute = false;   
  24.   
  25.         p = Process.Start(start);  
  26.   
  27.         reader = p.StandardOutput;   
  28.   
  29.         string line = reader.ReadLine();   
  30.   
  31.         while (!reader.EndOfStream)  
  32.         {  
  33.             if (line.ToLower().IndexOf("physical address") > 0 || line.ToLower().IndexOf("物理地址") > 0)  
  34.             {  
  35.                 int index = line.IndexOf(":");  
  36.                 index += 2;  
  37.                 macAddress = line.Substring(index);  
  38.                 macAddress = macAddress.Replace('-'':');  
  39.                 break;  
  40.             }  
  41.             line = reader.ReadLine();  
  42.         }  
  43.     }  
  44.     catch  
  45.     {  
  46.   
  47.     }  
  48.     finally  
  49.     {  
  50.         if (p != null)  
  51.         {  
  52.             p.WaitForExit();   
  53.             p.Close();   
  54.         }  
  55.         if (reader != null)  
  56.         {  
  57.             reader.Close();   
  58.         }  
  59.     }  
  60.     return macAddress;  
  61. }  

5、 NetworkInterface获取MAC地址

NetworkInterface,提供网络接口的配置和统计信息。NetworkInterface.GetAllNetworkInterfaces,返回描述本地计算机上的网络接口的对象。

代码如下:

 

[csharp]  view plain  copy
 print ?
  1. /// <summary>  
  2. /// 通过网络适配器获取MAC地址  
  3. /// </summary>  
  4. /// <returns></returns>  
  5. public string GetMacAddressByNetworkInformation()  
  6. {  
  7.     string macAddress = "";  
  8.     try  
  9.     {  
  10.         NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();  
  11.         foreach (NetworkInterface adapter in nics)  
  12.         {  
  13.             if (!adapter.GetPhysicalAddress().ToString().Equals(""))  
  14.             {  
  15.                 macAddress = adapter.GetPhysicalAddress().ToString();  
  16.                 for (int i = 1; i < 6; i++)  
  17.                 {  
  18.                     macAddress = macAddress.Insert(3 * i - 1, ":");  
  19.                 }  
  20.                 break;  
  21.             }  
  22.         }  
  23.   
  24.     }  
  25.     catch  
  26.     {  
  27.     }  
  28.     return macAddress;  
  29. }  

完整代码下载地址:http://download.csdn.net/download/yysyangyangyangshan/3949946



  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值