c#獲取Mac地址最全方法


 最近項目中需要用到獲取Mac地址,發現網上的N種方法都有缺陷,沒有准確定位Mac地址,不同的設備差異特別大。

 經過一番研究后,發現最好的方式是截圖命令獲取:

ipconfig/all

使用CMD命令這將面臨語言編碼問題,於是一番查找,發現一下命令可以讓系統默認采用美國英文來顯示命令:

chcp 437
MacAddress = MacAddressHelper.GetMacByIpConfig() ?? MacAddressHelper.GetMacByWmi().FirstOrDefault() ?? "unknown";
   /// <summary>
    /// Mac地址獲取幫助類 2019.10.16
    /// </summary>
    public class MacAddressHelper
    {
        ///<summary>
        /// 根據截取ipconfig /all命令的輸出流獲取網卡Mac,支持不同語言編碼
        ///</summary>
        ///<returns></returns>
        public static string GetMacByIpConfig()
        {
            List<string> macs = new List<string>();

            var runCmd = Cmd.RunCmd("chcp 437&&ipconfig/all");

            foreach (var line in runCmd.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Select(l => l.Trim()))
            {
                if (!string.IsNullOrEmpty(line))
                {
                    if (line.StartsWith("Physical Address"))
                    {
                        macs.Add(line.Substring(36));
                    }
                    else if (line.StartsWith("DNS Servers") && line.Length > 36 && line.Substring(36).Contains("::"))
                    {
                        macs.Clear();
                    }
                    else if (macs.Count > 0 && line.StartsWith("NetBIOS") && line.Contains("Enabled"))
                    {
                        return macs.Last();
                    }
                }
            }

            return macs.FirstOrDefault();
        }

        ///<summary>
        /// 通過WMI讀取系統信息里的網卡MAC
        ///</summary>
        ///<returns></returns>
        public static List<string> GetMacByWmi()
        {
            try
            {
                List<string> macs = new List<string>();
                ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
                ManagementObjectCollection moc = mc.GetInstances();
                foreach (ManagementObject mo in moc)
                {
                    if ((bool)mo["IPEnabled"])
                    {
                        var mac = mo["MacAddress"].ToString();
                        macs.Add(mac);
                    }
                }
                return macs;
            }
            catch (Exception e)
            {
                return null;
            }
        }

        ///<summary>
        /// 通過NetworkInterface讀取網卡Mac
        ///</summary>
        ///<returns></returns>
        public static List<string> GetMacByNetworkInterface()
        {
            List<string> macs = new List<string>();
            NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces();
            foreach (NetworkInterface ni in interfaces)
            {
                macs.Add(ni.GetPhysicalAddress().ToString());
            }
            return macs;
        }

        ///<summary>
        /// 通過SendARP獲取網卡Mac
        /// 網絡被禁用或未接入網絡(如沒插網線)時此方法失靈
        ///</summary>
        ///<param name="remoteIP"></param>
        ///<returns></returns>
        public static string GetMacBySendArp(string remoteIP)
        {
            StringBuilder macAddress = new StringBuilder();
            try
            {
                Int32 remote = inet_addr(remoteIP);
                Int64 macInfo = new Int64();
                Int32 length = 6;
                SendARP(remote, 0, ref macInfo, ref length);
                string temp = Convert.ToString(macInfo, 16).PadLeft(12, '0').ToUpper();
                int x = 12;
                for (int i = 0; i < 6; i++)
                {
                    if (i == 5)
                    {
                        macAddress.Append(temp.Substring(x - 2, 2));
                    }
                    else
                    {
                        macAddress.Append(temp.Substring(x - 2, 2) + "-");
                    }
                    x -= 2;
                }
                return macAddress.ToString();
            }
            catch
            {
                return macAddress.ToString();
            }
        }

        [DllImport("Iphlpapi.dll")]
        private static extern int SendARP(Int32 dest, Int32 host, ref Int64 mac, ref Int32 length);
        [DllImport("Ws2_32.dll")]
        private static extern Int32 inet_addr(string ip);

        class Cmd
        {
            private static string CmdPath = @"C:\Windows\System32\cmd.exe";
            /// <summary>
            /// 執行cmd命令 返回cmd窗口顯示的信息
            /// 多命令請使用批處理命令連接符:
            /// <![CDATA[
            /// &:同時執行兩個命令
            /// |:將上一個命令的輸出,作為下一個命令的輸入
            /// &&:當&&前的命令成功時,才執行&&后的命令
            /// ||:當||前的命令失敗時,才執行||后的命令]]>
            /// </summary>
            /// <param name="cmd">執行的命令</param>
            public static string RunCmd(string cmd)
            {
                cmd = cmd.Trim().TrimEnd('&') + "&exit";//說明:不管命令是否成功均執行exit命令,否則當調用ReadToEnd()方法時,會處於假死狀態
                using (Process p = new Process())
                {
                    p.StartInfo.FileName = CmdPath;
                    p.StartInfo.UseShellExecute = false;        //是否使用操作系統shell啟動
                    p.StartInfo.RedirectStandardInput = true;   //接受來自調用程序的輸入信息
                    p.StartInfo.RedirectStandardOutput = true;  //由調用程序獲取輸出信息
                    p.StartInfo.RedirectStandardError = true;   //重定向標准錯誤輸出
                    p.StartInfo.CreateNoWindow = true;          //不顯示程序窗口
                    p.Start();//啟動程序

                    //向cmd窗口寫入命令
                    p.StandardInput.WriteLine(cmd);
                    p.StandardInput.AutoFlush = true;

                    //獲取cmd窗口的輸出信息
                    string output = p.StandardOutput.ReadToEnd();
                    p.WaitForExit();//等待程序執行完退出進程
                    p.Close();

                    return output;
                }
            }
        }
    }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM