Mac-Adresse von Ethernet-Adapter Lan-Verbindung

  • Hallo,

    ich habe bereits im Forum bisher erfolglos recherchiert. Es gibt sehr viele Beiträge, die beim Aufinden von Mac-Adressen zu Lösungswegen führen, aber dennoch nicht mein spezielles Problem lösen.

    Ich benötige zunächst grundsätzlich die erste Mac-Adresse der "Ethernet-Adapter Lan-Verbindung". Dies alleine stellt ja kein allzu grosses Problem dar.

    Bsp.

    Spoiler anzeigen
    [autoit]


    RunWait(@ComSpec & " /c ipconfig /all > " & @TempDir&"\ipconfig.txt", "", @SW_HIDE)
    .. suche in IPCONFIG.TXT den Text "Ethernet-Adapter Lan-Verbindung"
    .. suche darauffolgenden Text "Physikalische Adresse"
    .. nimm die letzten 17 Stellen .. Voila

    [/autoit]

    Soweit so gut. Ich brauche das nun auch für englisch. Also frage ich vorher den Language Code ab.
    0407 = deutsch
    0409 = englisch
    Die Suchtexte für englisch wären dann "Ethernet adapter Local Area Connection" und "Physical Address".

    Nun entzieht sich aber meiner Kenntnis wie die Suchtexte in anderen ausländischen Versionen lauten. Damit das Programm zuverlässig die Mac-Adresse der LAN-Karte (auch wenn sie gerade nicht aktiv ist - weil z.B. die WLAN-Verbindung läuft) auch dort ermitteln kann, suche ich einen passenden Lösungsweg ohne den Language Code.
    Ich möchte noch mal darauf hinweisen, dass ich die Mac-Adresse der LAN-Karte ermitteln möchte, egal welche Netzwerkverbindung gerade aktiv ist.
    Hat da jemand eine Idee, wie ich das bewerkstelligen könnte ?

    Vielen Dank im voraus.
    MfG ExBerliner

  • Ich denke du solltest lieber auf eine sprachunabhängige Methode umschwenken.
    Z.B. die Informationen über WMI ziehen.
    Mal als kleiner Gedankenanstoß:

    [autoit]

    $o_WMI = ObjGet("winmgmts:\\localhost\root\CIMV2")
    For $x In $o_WMI.ExecQuery("SELECT * FROM Win32_NetworkAdapter " & _
    "WHERE ((MACAddress Is Not NULL) AND (Manufacturer <> " & _
    "'Microsoft') AND (PhysicalAdapter = True))", "WQL", 0x10 + 0x20)

    MsgBox(0,"", "Name: " & $x.name & @CRLF & _
    "Hersteller: " & $x.Manufacturer & @CRLF & _
    "Mac-Adresse: " & $x.MACAddress)
    Next

    [/autoit]
  • AspirinJunkie

    vielen Dank für die schnelle Antwort.

    Leider ist mir die WMI-"Politik" zu hoch. Würde denn die Möglichkeit bestehen, das WHERE im SELECT zu erweitern, so dass nur die LAN-Karte zuverlässig ermittelt werden kann ?
    Oder gibt es bei $x.name etwas was ich mittels einer Suchfunktion verwenden kann, um eindeutig eine Ethernet LAN-Karte zu erkennen ? Ich denke mal der Ausschluss über "Broadcom" (mein WLAN-Adapter) wird mich bei der Fülle von Netzwerkadaptern nicht wirklich weiter bringen. Umgekehrt hilft mir da sicher auch nicht der Treffer über "Realtek" (in meinem Fall) die LAN-Karte heraus zu finden.

    [edit] ich stelle gerade fest, o.g. Script läuft nicht auf XP, sondern nur auf Win7 ? .. schade.

    MfG
    ExBerliner

    Einmal editiert, zuletzt von ExBerliner (9. Februar 2012 um 02:09)

  • Vielleicht bekommst du das richtige Ergebnis über den AdapterType.

    [autoit]

    ;http://msdn.microsoft.com/en-us/library/…6(v=vs.85).aspx

    [/autoit][autoit][/autoit][autoit]

    $o_WMI = ObjGet("winmgmts:\\localhost\root\CIMV2")
    For $x In $o_WMI.ExecQuery("SELECT * FROM Win32_NetworkAdapter " & _
    "WHERE ((MACAddress Is Not NULL) AND (Manufacturer <> 'Microsoft'))", "WQL", 0x10 + 0x20)

    [/autoit][autoit][/autoit][autoit]

    ;~ "NetEnabled: " & $x.NetEnabled & @CRLF & _

    [/autoit][autoit][/autoit][autoit]

    MsgBox(0,"", "Name: " & $x.name & @CRLF & _
    "Hersteller: " & $x.Manufacturer & @CRLF & _
    "AdapterType: " & $x.AdapterType & @CRLF & _
    "Mac-Adresse: " & $x.MACAddress)
    Next

    [/autoit]

    Die Methode PhysicalAdapter scheint ja unter WinXP nicht zu funktionieren.

  • funkey

    leider gehts auch über den AdapterType nicht eindeutig. Der Suchbegriff wäre hier "Ethernet 802.3".
    Hier sind neben meinen 2 Ergebnissen (LAN + WLAN-Adapter) durch AspirinJunkie noch weitere 6 Adapter von Connectify dann aufgeführt.

    Zwischenzeitlich habe ich mir Scriptomatic mal angeschaut und kann den Code auch nachvollziehen. Leider gibt es keine eindeutigen Ergebnisse. Zumindest funktionert der Code von Funkey unter XP und Win7.

    Hat vielleicht jemand einen anderen Lösungsweg ?

    MfG
    ExBerliner

  • Alternativ würde mir erstmal nur die GetAdaptersInfo-API-Funktion einfallen.
    Probiers mal damit:

    MAC-Adressen der LAN-Adapter im Rechner
    [autoit]

    #include <Array.au3>
    Global Const $tagIP_ADAPTER_INFO = "ptr Next;" & _
    "DWORD ComboIndex;" & _
    "char AdapterName[260];" & _
    "char Description[132];" & _
    "UINT AddressLength;" & _
    "BYTE Address[8];" & _
    "DWORD Index;" & _
    "UINT Type;" & _
    "UINT DhcpEnabled;" & _
    "ptr CurrentIpAddress;" & _
    "ptr IpAddressListNext;" & _
    "char IpAddressListADDRESS[16];" & _
    "char IpAddressListMASK[16];" & _
    "DWORD IpAddressListContext;" & _
    "ptr GatewayListNext;" & _
    "char GatewayListADDRESS[16];" & _
    "char GatewayListMASK[16];" & _
    "DWORD GatewayListContext;" & _
    "ptr DhcpServerNext;" & _
    "char DhcpServerADDRESS[16];" & _
    "char DhcpServerMASK[16];" & _
    "DWORD DhcpServerContext;" & _
    "BOOL HaveWins;" & _
    "ptr PrimaryWinsServerNext;" & _
    "char PrimaryWinsServerADDRESS[16];" & _
    "char PrimaryWinsServerMASK[16];" & _
    "DWORD PrimaryWinsServerContext;" & _
    "ptr SecondaryWinsServerNext;" & _
    "char SecondaryWinsServerADDRESS[16];" & _
    "char SecondaryWinsServerMASK[16];" & _
    "DWORD SecondaryWinsServerContext;" & _
    "DWORD LeaseObtained; DWORD LeaseExpires;"

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Global $a_LANAdapters = getMACsOfLANDevices()
    _ArrayDisplay($a_LANAdapters, "MAC-Adressen der LAN-Adapter")

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func getMACsOfLANDevices()
    ;by AspirinJunkie
    Local $a_Ret, $s_Ret = "", $buf_AdapterInfo, $p_AdapterInfo, $strct_AdapterInfo
    Local $h_dll = DllOpen("Iphlpapi.dll")

    [/autoit] [autoit][/autoit] [autoit]

    $a_Ret = DllCall($h_dll, "DWORD", "GetAdaptersInfo", "ptr", 0, "ULONG*", 0) ; 1. Call um ulOutBufLen zu bestimmen
    $buf_AdapterInfo = DllStructCreate("BYTE[" & $a_Ret[2] & "]")
    $p_AdapterInfo = DllStructGetPtr($buf_AdapterInfo)

    [/autoit] [autoit][/autoit] [autoit]

    DllCall($h_dll, "DWORD", "GetAdaptersInfo", "ptr", $p_AdapterInfo, "ULONG*", $a_Ret[2]) ; 2. Call welcher nun den 1. Adapter zurück gibt
    $strct_AdapterInfo = DllStructCreate($tagIP_ADAPTER_INFO, $p_AdapterInfo)

    [/autoit] [autoit][/autoit] [autoit]

    If Not @error Then
    Do
    ; Prüfe ob Adapter ein Ethernetadapter ist (WLan = 71)
    If DllStructGetData($strct_AdapterInfo, "Type") = 6 Then $s_Ret &= StringTrimRight(StringRegExpReplace(StringTrimLeft(DllStructGetData($strct_AdapterInfo, "Address"), 2), "(.{2})", "$1:"), 7) & ";"

    [/autoit] [autoit][/autoit] [autoit]

    $p_AdapterInfo = DllStructGetData($strct_AdapterInfo, "Next") ; nächsten Adapter holen
    $strct_AdapterInfo = DllStructCreate($tagIP_ADAPTER_INFO, $p_AdapterInfo)
    Until @error
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    DllClose($h_dll)
    Return StringSplit(StringTrimRight($s_Ret, 1), ";", 2)
    EndFunc ;==>getIndicesOfLANDevices

    [/autoit]
  • AspirinJunkie

    Dein letzter Code läuft unter XP und Win7 .. super.

    Nur, unter XP werden bei einem von 2 Rechnern mir im Listview 2 Adapter (LAN und WLAN) angezeigt. Unter Win7 scheint es eindeutig zu sein, auch hier waren WLAN-Adapter vorhanden.
    Repräsentiv ist das zwar nicht, aber leider noch nicht eindeutig.

    Bei dem fraglichen XP-PC exestieren "Ethernetadapter Drahtlose Netzwerkverbindung" und "Ethernetadapter LAN-Verbindung". Ich habe mir den Code zwar schon im Detail verinnerlicht, finde jedoch kein weiteres Auschlusskriterium.

    Ich muss mir das nochmals in Ruhe anschauen, denke aber nicht dass ich fähig sein werde, den Code anzupassen.

    Vielen Dank dass Ihr euch mit meinem "Problemchen" auseinandergesetzt habt.

    MfG
    ExBerliner

  • Man kann bei GetAdapterInfo auch den Index des Adapters ermitteln.
    Diesen wiederrum kann man dann dazu verwenden (oder auch gleich die MAC-Adresse) um die WMI-Ausgabe entsprechend zu filtern.
    Mal wieder ein kleines Beispiel:

    Spoiler anzeigen
    [autoit]

    Global Const $tagIP_ADAPTER_INFO = "ptr Next;" & _
    "DWORD ComboIndex;" & _
    "char AdapterName[260];" & _
    "char Description[132];" & _
    "UINT AddressLength;" & _
    "BYTE Address[8];" & _
    "DWORD Index;" & _
    "UINT Type;" & _
    "UINT DhcpEnabled;" & _
    "ptr CurrentIpAddress;" & _
    "ptr IpAddressListNext;" & _
    "char IpAddressListADDRESS[16];" & _
    "char IpAddressListMASK[16];" & _
    "DWORD IpAddressListContext;" & _
    "ptr GatewayListNext;" & _
    "char GatewayListADDRESS[16];" & _
    "char GatewayListMASK[16];" & _
    "DWORD GatewayListContext;" & _
    "ptr DhcpServerNext;" & _
    "char DhcpServerADDRESS[16];" & _
    "char DhcpServerMASK[16];" & _
    "DWORD DhcpServerContext;" & _
    "BOOL HaveWins;" & _
    "ptr PrimaryWinsServerNext;" & _
    "char PrimaryWinsServerADDRESS[16];" & _
    "char PrimaryWinsServerMASK[16];" & _
    "DWORD PrimaryWinsServerContext;" & _
    "ptr SecondaryWinsServerNext;" & _
    "char SecondaryWinsServerADDRESS[16];" & _
    "char SecondaryWinsServerMASK[16];" & _
    "DWORD SecondaryWinsServerContext;" & _
    "DWORD LeaseObtained; DWORD LeaseExpires;"

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Global $a_LANAdapters = getMACsOfLANDevices()

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Global $o_WMI = ObjGet("winmgmts:\\localhost\root\CIMV2")
    For $x In $o_WMI.ExecQuery("SELECT * FROM Win32_NetworkAdapter " & _
    "WHERE ((MACAddress Is Not NULL) AND (Manufacturer <> " & _
    "'Microsoft'))", "WQL", 0x10 + 0x20)

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To $a_LANAdapters[0][0]
    ConsoleWrite( $a_LANAdapters[$i][0] & @TAB & $x.InterfaceIndex & @CRLF) ; Prüfen ob Adapter in $a_LANAdapters vorhanden ist
    If $a_LANAdapters[$i][0] == $x.InterfaceIndex Then
    MsgBox(0, "", "Name: " & $x.name & @CRLF & _
    "Hersteller: " & $x.Manufacturer & @CRLF & _
    "Mac-Adresse: " & $x.MACAddress)
    EndIf
    Next
    Next

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func getMACsOfLANDevices()
    ;by AspirinJunkie
    Local $a_Ret, $a_Return[1][2], $buf_AdapterInfo, $p_AdapterInfo, $strct_AdapterInfo
    Local $h_dll = DllOpen("Iphlpapi.dll")

    [/autoit] [autoit][/autoit] [autoit]

    $a_Ret = DllCall($h_dll, "DWORD", "GetAdaptersInfo", "ptr", 0, "ULONG*", 0) ; 1. Call um ulOutBufLen zu bestimmen
    $buf_AdapterInfo = DllStructCreate("BYTE[" & $a_Ret[2] & "]")
    $p_AdapterInfo = DllStructGetPtr($buf_AdapterInfo)

    [/autoit] [autoit][/autoit] [autoit]

    DllCall($h_dll, "DWORD", "GetAdaptersInfo", "ptr", $p_AdapterInfo, "ULONG*", $a_Ret[2]) ; 2. Call welcher nun den 1. Adapter zurück gibt
    $strct_AdapterInfo = DllStructCreate($tagIP_ADAPTER_INFO, $p_AdapterInfo)

    [/autoit] [autoit][/autoit] [autoit]

    If Not @error Then
    Do
    ; Prüfe ob Adapter ein Ethernetadapter ist (WLan = 71)
    If DllStructGetData($strct_AdapterInfo, "Type") = 6 Then
    ReDim $a_Return[UBound($a_Return) + 1][2]
    $a_Return[0][0] += 1
    $a_Return[UBound($a_Return) - 1][0] = DllStructGetData($strct_AdapterInfo, "Index")
    $a_Return[UBound($a_Return) - 1][1] = StringTrimRight(StringRegExpReplace(StringTrimLeft(DllStructGetData($strct_AdapterInfo, "Address"), 2), "(.{2})", "$1:"), 7)
    EndIf
    $p_AdapterInfo = DllStructGetData($strct_AdapterInfo, "Next") ; nächsten Adapter holen
    $strct_AdapterInfo = DllStructCreate($tagIP_ADAPTER_INFO, $p_AdapterInfo)
    Until @error
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    DllClose($h_dll)
    Return $a_Return
    EndFunc ;==>getMACsOfLANDevices

    [/autoit]

    Edit: Oder das ganze etwas vereinfacht:

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    Global Const $tagIP_ADAPTER_INFO = "ptr Next;" & _
    "DWORD ComboIndex;" & _
    "char AdapterName[260];" & _
    "char Description[132];" & _
    "UINT AddressLength;" & _
    "BYTE Address[8];" & _
    "DWORD Index;" & _
    "UINT Type;" & _
    "UINT DhcpEnabled;" & _
    "ptr CurrentIpAddress;" & _
    "ptr IpAddressListNext;" & _
    "char IpAddressListADDRESS[16];" & _
    "char IpAddressListMASK[16];" & _
    "DWORD IpAddressListContext;" & _
    "ptr GatewayListNext;" & _
    "char GatewayListADDRESS[16];" & _
    "char GatewayListMASK[16];" & _
    "DWORD GatewayListContext;" & _
    "ptr DhcpServerNext;" & _
    "char DhcpServerADDRESS[16];" & _
    "char DhcpServerMASK[16];" & _
    "DWORD DhcpServerContext;" & _
    "BOOL HaveWins;" & _
    "ptr PrimaryWinsServerNext;" & _
    "char PrimaryWinsServerADDRESS[16];" & _
    "char PrimaryWinsServerMASK[16];" & _
    "DWORD PrimaryWinsServerContext;" & _
    "ptr SecondaryWinsServerNext;" & _
    "char SecondaryWinsServerADDRESS[16];" & _
    "char SecondaryWinsServerMASK[16];" & _
    "DWORD SecondaryWinsServerContext;" & _
    "DWORD LeaseObtained; DWORD LeaseExpires;"

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Global $o_WMI = ObjGet("winmgmts:\\localhost\root\CIMV2")

    [/autoit] [autoit][/autoit] [autoit]

    For $s_Mac In getMACsOfLANDevices()
    For $x In $o_WMI.ExecQuery("SELECT * FROM Win32_NetworkAdapter " & _
    "WHERE ((MACAddress = '" & $s_Mac & "') AND (Manufacturer <> " & _
    "'Microsoft'))", "WQL", 0x10 + 0x20)
    MsgBox(0, "", "Name: " & $x.name & @CRLF & _
    "Hersteller: " & $x.Manufacturer & @CRLF & _
    "Mac-Adresse: " & $x.MACAddress)
    Next
    Next

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func getMACsOfLANDevices()
    ;by AspirinJunkie
    Local $a_Ret, $s_Ret = "", $buf_AdapterInfo, $p_AdapterInfo, $strct_AdapterInfo
    Local $h_dll = DllOpen("Iphlpapi.dll")

    [/autoit] [autoit][/autoit] [autoit]

    $a_Ret = DllCall($h_dll, "DWORD", "GetAdaptersInfo", "ptr", 0, "ULONG*", 0) ; 1. Call um ulOutBufLen zu bestimmen
    $buf_AdapterInfo = DllStructCreate("BYTE[" & $a_Ret[2] & "]")
    $p_AdapterInfo = DllStructGetPtr($buf_AdapterInfo)

    [/autoit] [autoit][/autoit] [autoit]

    DllCall($h_dll, "DWORD", "GetAdaptersInfo", "ptr", $p_AdapterInfo, "ULONG*", $a_Ret[2]) ; 2. Call welcher nun den 1. Adapter zurück gibt
    $strct_AdapterInfo = DllStructCreate($tagIP_ADAPTER_INFO, $p_AdapterInfo)

    [/autoit] [autoit][/autoit] [autoit]

    If Not @error Then
    Do
    ; Prüfe ob Adapter ein Ethernetadapter ist (WLan = 71)
    If DllStructGetData($strct_AdapterInfo, "Type") = 6 Then $s_Ret &= StringTrimRight(StringRegExpReplace(StringTrimLeft(DllStructGetData($strct_AdapterInfo, "Address"), 2), "(.{2})", "$1:"), 7) & ";"

    [/autoit] [autoit][/autoit] [autoit]

    $p_AdapterInfo = DllStructGetData($strct_AdapterInfo, "Next") ; nächsten Adapter holen
    $strct_AdapterInfo = DllStructCreate($tagIP_ADAPTER_INFO, $p_AdapterInfo)
    Until @error
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    DllClose($h_dll)
    Return StringSplit(StringTrimRight($s_Ret, 1), ";", 2)
    EndFunc ;==>getMACsOfLANDevices

    [/autoit]

    Vielleicht kannst du aus der Komination von GetAdaptersInfo und WMI das ganze sicherer ausschließen weil der Wert 71 für den Typ WLan erst ab Vista existiert.
    Im schlimmsten Fall musst du dir die Bezeichnung nehmen und bei "netsh wlan show interfaces" nachschauen ob die MAC-Adresse dort vorkommt oder nicht um WLAN-Geräte auszuschließen.

    3 Mal editiert, zuletzt von AspirinJunkie (9. Februar 2012 um 15:45)

  • @all

    ich habe die vorherigen Codes mal angetestet. Die Routinen liefern jede für sich leider keine eindeutigen Ergebnisse.
    Ich mache mich dann mal ans Werk, eine Kombination aus beidem zu verwenden.

    Da ich mich damit im Detail beschäftigen muss und will, wird es wohl auch etwas dauern.

    Vielen Dank für Eure Mühe.

    MfG
    ExBerliner