[C#] C #에서 컴퓨터의 MAC 주소를 얻는 안정적인 방법

C #을 사용하여 실행중인 OS에 관계없이 컴퓨터의 MAC 주소를 얻는 방법이 필요합니다. 응용 프로그램은 XP / Vista / Win7 32 및 64 비트 및 해당 OS에서 작동해야하지만 외국어는 기본적으로 작동해야합니다. 많은 C # 명령 및 OS 쿼리가 OS에서 작동하지 않습니다. 어떤 아이디어? “ipconfig / all”의 출력을 긁어 냈지만 출력 형식이 모든 컴퓨터마다 다르기 때문에 이것은 신뢰할 수 없습니다.

감사



답변

클리너 솔루션

var macAddr = 
    (
        from nic in NetworkInterface.GetAllNetworkInterfaces()
        where nic.OperationalStatus == OperationalStatus.Up
        select nic.GetPhysicalAddress().ToString()
    ).FirstOrDefault();

또는:

String firstMacAddress = NetworkInterface
    .GetAllNetworkInterfaces()
    .Where( nic => nic.OperationalStatus == OperationalStatus.Up && nic.NetworkInterfaceType != NetworkInterfaceType.Loopback )
    .Select( nic => nic.GetPhysicalAddress().ToString() )
    .FirstOrDefault();


답변

첫 번째 운영 네트워크 인터페이스의 MAC 주소를 반환하는 C # 코드가 있습니다. NetworkInterface어셈블리가 다른 운영 체제에서 사용되는 런타임 (예 : Mono)으로 구현 되었다고 가정하면 다른 운영 체제에서도 작동합니다.

새 버전 : 유효한 MAC 주소를 가진 가장 빠른 속도로 NIC를 반환합니다.

/// <summary>
/// Finds the MAC address of the NIC with maximum speed.
/// </summary>
/// <returns>The MAC address.</returns>
private string GetMacAddress()
{
    const int MIN_MAC_ADDR_LENGTH = 12;
    string macAddress = string.Empty;
    long maxSpeed = -1;

    foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
    {
        log.Debug(
            "Found MAC Address: " + nic.GetPhysicalAddress() +
            " Type: " + nic.NetworkInterfaceType);

        string tempMac = nic.GetPhysicalAddress().ToString();
        if (nic.Speed > maxSpeed &&
            !string.IsNullOrEmpty(tempMac) &&
            tempMac.Length >= MIN_MAC_ADDR_LENGTH)
        {
            log.Debug("New Max Speed = " + nic.Speed + ", MAC: " + tempMac);
            maxSpeed = nic.Speed;
            macAddress = tempMac;
        }
    }

    return macAddress;
}

원본 버전 : 첫 번째 버전 만 반환합니다.

/// <summary>
/// Finds the MAC address of the first operation NIC found.
/// </summary>
/// <returns>The MAC address.</returns>
private string GetMacAddress()
{
    string macAddresses = string.Empty;

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

    return macAddresses;
}

Nortel Packet Miniport 또는 VPN 연결 유형이 마음에 든다면 선택 가능성이 있습니다. 내가 알 수있는 한 실제 물리적 장치의 MAC을 어떤 유형의 가상 네트워크 인터페이스와 구별 할 수있는 방법이 없습니다.


답변

Win32_NetworkAdapterConfiguration WMI 클래스MACAddress 속성은 어댑터의 MAC 주소를 제공 할 수 있습니다. (System.Management 네임 스페이스)

MACAddress

    Data type: string
    Access type: Read-only

    Media Access Control (MAC) address of the network adapter. A MAC address is assigned by the manufacturer to uniquely identify the network adapter.

    Example: "00:80:C7:8F:6C:96"

WMI API (Windows Management Instrumentation)에 익숙하지 않은 경우 .NET 앱에 대한 좋은 개요가 있습니다 .

WMI는 .Net 런타임으로 모든 버전의 창에서 사용할 수 있습니다.

코드 예제는 다음과 같습니다.

System.Management.ManagementClass mc = default(System.Management.ManagementClass);
ManagementObject mo = default(ManagementObject);
mc = new ManagementClass("Win32_NetworkAdapterConfiguration");

ManagementObjectCollection moc = mc.GetInstances();
    foreach (var mo in moc) {
        if (mo.Item("IPEnabled") == true) {
              Adapter.Items.Add("MAC " + mo.Item("MacAddress").ToString());
         }
     }


답변

WMI는 연결하는 시스템이 Windows 시스템 인 경우 가장 좋은 솔루션이지만 Linux, mac 또는 기타 유형의 네트워크 어댑터를보고있는 경우 다른 것을 사용해야합니다. 몇 가지 옵션이 있습니다.

  1. DOS 명령 nbtstat -a를 사용하십시오. 프로세스를 작성하고이 명령을 호출하여 출력을 구문 분석하십시오.
  2. 먼저 IP를 Ping하여 NIC가 ARP 테이블에 명령을 캐시하는지 확인한 다음 DOS 명령 arp -a를 사용하십시오. 옵션 1과 같이 프로세스 출력을 구문 분석하십시오.
  3. iphlpapi.dll에서 무서운 관리되지 않는 호출을 사용하여 sendarp

다음은 항목 # 3의 샘플입니다. WMI가 실행 가능한 솔루션이 아닌 경우 이것이 가장 좋은 옵션 인 것 같습니다.

using System.Runtime.InteropServices;
...
[DllImport("iphlpapi.dll", ExactSpelling = true)]
        public static extern int SendARP(int DestIP, int SrcIP, byte[] pMacAddr, ref uint PhyAddrLen);
...
private string GetMacUsingARP(string IPAddr)
{
    IPAddress IP = IPAddress.Parse(IPAddr);
    byte[] macAddr = new byte[6];
    uint macAddrLen = (uint)macAddr.Length;

    if (SendARP((int)IP.Address, 0, macAddr, ref macAddrLen) != 0)
        throw new Exception("ARP command failed");

    string[] str = new string[(int)macAddrLen];
    for (int i = 0; i < macAddrLen; i++)
        str[i] = macAddr[i].ToString("x2");

    return string.Join(":", str);
}

마감일을 밝히기 위해 해당 코드의 기초는 다음과 같습니다.
http://www.pinvoke.net/default.aspx/iphlpapi.sendarp#


답변

WMI를 사용하여 메트릭이 가장 낮은 인터페이스의 mac 주소를 가져옵니다. 예를 들어 인터페이스 창은 다음과 같이 선호합니다.

public static string GetMACAddress()
{
    ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration where IPEnabled=true");
    IEnumerable<ManagementObject> objects = searcher.Get().Cast<ManagementObject>();
    string mac = (from o in objects orderby o["IPConnectionMetric"] select o["MACAddress"].ToString()).FirstOrDefault();
    return mac;
}

또는 Silverlight (신뢰가 필요) :

public static string GetMACAddress()
{
    string mac = null;
    if ((Application.Current.IsRunningOutOfBrowser) && (Application.Current.HasElevatedPermissions) && (AutomationFactory.IsAvailable))
    {
        dynamic sWbemLocator = AutomationFactory.CreateObject("WbemScripting.SWBemLocator");
        dynamic sWbemServices = sWbemLocator.ConnectServer(".");
        sWbemServices.Security_.ImpersonationLevel = 3; //impersonate

        string query = "SELECT * FROM Win32_NetworkAdapterConfiguration where IPEnabled=true";
        dynamic results = sWbemServices.ExecQuery(query);

        int mtu = int.MaxValue;
        foreach (dynamic result in results)
        {
            if (result.IPConnectionMetric < mtu)
            {
                mtu = result.IPConnectionMetric;
                mac = result.MACAddress;
            }
        }
    }
    return mac;
}


답변

public static PhysicalAddress GetMacAddress()
{
    var myInterfaceAddress = NetworkInterface.GetAllNetworkInterfaces()
        .Where(n => n.OperationalStatus == OperationalStatus.Up && n.NetworkInterfaceType != NetworkInterfaceType.Loopback)
        .OrderByDescending(n => n.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
        .Select(n => n.GetPhysicalAddress())
        .FirstOrDefault();

    return myInterfaceAddress;
}


답변

첫 번째 mac 주소를 반환하는 IMHO는 특히 가상 컴퓨터가 호스팅되는 경우 좋지 않습니다. 따라서 보내기 / 받기 바이트 합계를 확인하고 가장 많이 사용되는 연결을 선택하십시오. 완벽하지는 않지만 9/10 번 정확해야합니다.

public string GetDefaultMacAddress()
{
    Dictionary<string, long> macAddresses = new Dictionary<string, long>();
    foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
    {
        if (nic.OperationalStatus == OperationalStatus.Up)
            macAddresses[nic.GetPhysicalAddress().ToString()] = nic.GetIPStatistics().BytesSent + nic.GetIPStatistics().BytesReceived;
    }
    long maxValue = 0;
    string mac = "";
    foreach(KeyValuePair<string, long> pair in macAddresses)
    {
        if (pair.Value > maxValue)
        {
            mac = pair.Key;
            maxValue = pair.Value;
        }
    }
    return mac;
}