Как получить значимые имена сетевых интерфейсов вместо идентификаторов GUID с netifaces под Windows?

Я использую netifaces модуль.

import netifaces
print netifaces.interfaces()

но это показывает результат ниже:

 ['{CDC97813-CC28-4260-BA1E-F0CE3081DEC7}',
 '{846EE342-7039-11DE-9D20-806E6F6E6963}',
 '{A51BA5F0-738B-4405-975F-44E67383513F}',
 '{A646FA85-2EC6-4E57-996E-96E1B1C5CD59}',
'{B5DC7787-26DC-4540-8424-A1D5598DC175}']

Я хочу получить "дружественное" имя интерфейса, такое как "Подключение по локальной сети" в Windows.

Как я могу получить это?

7 ответов

Решение

Это выглядит как netifaces нам остается только вытащить информацию из реестра Windows. Следующие функции работают для меня под Python 3.4 на Windows 8.1.

Чтобы получить имя подключения...

import netifaces as ni
import winreg as wr
from pprint import pprint

def get_connection_name_from_guid(iface_guids):
    iface_names = ['(unknown)' for i in range(len(iface_guids))]
    reg = wr.ConnectRegistry(None, wr.HKEY_LOCAL_MACHINE)
    reg_key = wr.OpenKey(reg, r'SYSTEM\CurrentControlSet\Control\Network\{4d36e972-e325-11ce-bfc1-08002be10318}')
    for i in range(len(iface_guids)):
        try:
            reg_subkey = wr.OpenKey(reg_key, iface_guids[i] + r'\Connection')
            iface_names[i] = wr.QueryValueEx(reg_subkey, 'Name')[0]
        except FileNotFoundError:
            pass
    return iface_names

x = ni.interfaces()
pprint(get_connection_name_from_guid(x))

.. который на моей машине производит:

['Local Area Connection* 12',
 'Bluetooth Network Connection',
 'Wi-Fi',
 'Ethernet',
 'VirtualBox Host-Only Network',
 '(unknown)',
 'isatap.{4E4150B0-643B-42EA-AEEA-A14FBD6B1844}',
 'isatap.{BB05D283-4CBF-4514-B76C-7B7EBB2FC85B}']

Чтобы получить имя водителя...

import netifaces as ni
import winreg as wr
from pprint import pprint

def get_driver_name_from_guid(iface_guids):
    iface_names = ['(unknown)' for i in range(len(iface_guids))]
    reg = wr.ConnectRegistry(None, wr.HKEY_LOCAL_MACHINE)
    reg_key = wr.OpenKey(reg, r'SYSTEM\CurrentControlSet\Control\Class\{4d36e972-e325-11ce-bfc1-08002be10318}')
    for i in range(wr.QueryInfoKey(reg_key)[0]):
        subkey_name = wr.EnumKey(reg_key, i)
        try:
            reg_subkey = wr.OpenKey(reg_key, subkey_name)
            guid = wr.QueryValueEx(reg_subkey, 'NetCfgInstanceId')[0]
            try:
                idx = iface_guids.index(guid)
                iface_names[idx] = wr.QueryValueEx(reg_subkey, 'DriverDesc')[0]
            except ValueError:
                pass
        except PermissionError:
            pass
    return iface_names

x = ni.interfaces()
pprint(get_driver_name_from_guid(x))

... что дает мне:

['Microsoft Wi-Fi Direct Virtual Adapter',
 'Bluetooth Device (Personal Area Network)',
 'Dell Wireless 1395 WLAN Mini-Card',
 'Broadcom 440x 10/100 Integrated Controller',
 'VirtualBox Host-Only Ethernet Adapter',
 '(unknown)',
 'Microsoft ISATAP Adapter',
 'Microsoft ISATAP Adapter']

Модуль Scapy имеет встроенный get_windows_if_list() это работает хорошо. (Я немного сократил вывод)

Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from scapy.all import *
>>> get_windows_if_list()
[
    {'name': 'Realtek USB GbE Family Controller', 'win_index': '17', 'description': 'Ethernet', 'guid': '<guid>', 'mac': '<mac>', 'netid': 'Ethernet'},  
    {'name': 'Intel(R) Dual Band Wireless-AC 8260', 'win_index': '5', 'description': 'Wi-Fi', 'guid': '<guid>', 'mac': '<mac>', 'netid': 'Wi-Fi'}
]

Здесь

документация Scapy (scapy.interfaces.NetworkInterface) Класс NetworkInterface имеет несколько переменных данных

      class NetworkInterface(object):
def __init__(self,
             provider,  # type: InterfaceProvider
             data=None,  # type: Optional[Dict[str, Any]]
             ):
    # type: (...) -> None
    self.provider = provider
    self.name = ""
    self.description = ""
    self.network_name = ""
    self.index = -1
    self.ip = None  # type: Optional[str]
    self.ips = defaultdict(list)  # type: DefaultDict[int, List[str]]
    self.mac = None  # type: Optional[str]
    self.dummy = False
    if data is not None:
        self.update(data)

вот как вы можете получить имя

      from scapy.all import *
l=get_if_list()
dict=IFACES.data
for item in l:
    print(dic[item].name)

вот как вы можете получить имя водителя

      from scapy.all import *
l=get_if_list()
dict=IFACES.data
for item in l:
    print(dic[item].description)

Мы также можем использовать Windows WMI:

import wmi

c = wmi.WMI()
qry = "select Name from Win32_NetworkAdapter where NetEnabled=True and NetConnectionStatus=2"

lst = [o.Name for o in c.query(qry)]
print(lst)

дает на моей машине:

['Realtek PCIe GBE Family Controller', 'VMware Virtual Ethernet Adapter for VMnet1', 'VMware Virtual Ethernet Adapter for VMnet8', 'VirtualBox Host-Only Ethernet Adapter']

MSDN: класс Win32_NetworkAdapter

Если вы знаете IP-адрес, который использует ваш интерфейс, вы можете просто сделать что-то вроде этого:

import netifaces as ni
def get_interfaces():
    ifaces = ni.interfaces()
    for iface in ifaces:
        try:
            ip = ni.ifaddresses(iface)[ni.AF_INET][0]["addr"]
            print(f"IP: {ip} from Interface {iface}")
        except:
            pass

Распространение ответа MaxU

Более точный / изысканный способ

Select Index from Win32_NetworkAdapterConfiguration WHERE IPEnabled = True or (ServiceName<>'' 
                                                    AND ServiceName<>'AsyncMac' 
                                                    AND ServiceName<>'VMnetx' AND ServiceName<>'VMnetadapter' AND ServiceName<>'Rasl2tp' AND ServiceName<>'msloop' AND ServiceName<>'PptpMiniport' 
                                                    AND ServiceName<>'Raspti' AND ServiceName<>'NDISWan' AND ServiceName<>'NdisWan4' AND ServiceName<>'RasPppoe' 
                                                    AND ServiceName<>'NdisIP' AND Description<>'PPP Adapter.') AND MACAddress is not NULL

а затем запустить запрос относительно

SELECT * FROM Win32_NetworkAdapter where index= <Index>

В PowerShell все намного проще:

Get-WmiObject -Class Win32_NetworkAdapterConfiguration | 
    Select-Object Description, SettingID, MACAddress | 
    Format-Table -AutoSize
Другие вопросы по тегам