求获取Windows所有可用MAC ID的Python非subprocess替代方案
不用subprocess获取Windows MAC地址的替代方案
当然有合适的替代方案啦!不用调用subprocess执行系统命令,我们可以直接通过Python调用Windows原生API或者利用WMI接口来获取MAC地址,这样既避免了解析命令输出的麻烦,也更高效稳定。下面给你两种实用的实现:
方案一:用ctypes直接调用Windows原生API(无额外依赖)
这种方法不需要安装任何第三方库,直接借助Python的ctypes模块调用Windows的GetAdaptersAddresses API——这是Windows系统提供的标准网络信息查询接口,精准度拉满。
import ctypes import struct # 定义Windows API需要的结构体(只保留我们需要的核心字段) class IP_ADAPTER_ADDRESSES(ctypes.Structure): pass IP_ADAPTER_ADDRESSES._fields_ = [ ("Length", ctypes.c_ulong), ("IfIndex", ctypes.c_ulong), ("Next", ctypes.POINTER(IP_ADAPTER_ADDRESSES)), ("FriendlyName", ctypes.c_char_p), ("PhysicalAddress", ctypes.c_ubyte * 8), ("PhysicalAddressLength", ctypes.c_ulong), ] def get_mac_addresses(): mac_list = [] # 初始分配内存缓冲区 buffer_size = ctypes.c_ulong(15000) buffer = ctypes.c_buffer(buffer_size.value) # 调用GetAdaptersAddresses获取适配器信息 result = ctypes.windll.iphlpapi.GetAdaptersAddresses( 0, 0, None, ctypes.byref(buffer), ctypes.byref(buffer_size) ) # 如果初始缓冲区不够,重新分配后再次调用 if result != 0: buffer = ctypes.c_buffer(buffer_size.value) result = ctypes.windll.iphlpapi.GetAdaptersAddresses( 0, 0, None, ctypes.byref(buffer), ctypes.byref(buffer_size) ) if result == 0: adapter = ctypes.cast(buffer, ctypes.POINTER(IP_ADAPTER_ADDRESSES)).contents while adapter: # 提取有效MAC地址(过滤长度为0的无效项) if adapter.PhysicalAddressLength > 0: mac_bytes = adapter.PhysicalAddress[:adapter.PhysicalAddressLength] mac_str = ":".join(f"{b:02X}" for b in mac_bytes) mac_list.append(mac_str) # 遍历下一个适配器 adapter = adapter.Next.contents if adapter.Next else None return mac_list # 测试调用 if __name__ == "__main__": macs = get_mac_addresses() print("所有可用MAC地址:") for mac in macs: print(mac)
这个代码直接和系统底层交互,不会有命令输出解析的兼容性问题,还能获取到所有网络适配器的MAC地址(包括虚拟适配器)。
方案二:用WMI模块(更简洁,需安装依赖)
如果你觉得API调用有点繁琐,可以用WMI模块——它封装了Windows的WMI接口,代码会更简洁易懂。不过需要先安装依赖:
pip install wmi
然后实现代码:
import wmi def get_mac_addresses(): mac_list = [] wmi_client = wmi.WMI() # 查询启用了IP的网络适配器(如果要包含禁用的适配器,去掉IPEnabled=True即可) for adapter in wmi_client.Win32_NetworkAdapterConfiguration(IPEnabled=True): if adapter.MACAddress: mac_list.append(adapter.MACAddress) return mac_list # 测试调用 if __name__ == "__main__": macs = get_mac_addresses() print("所有可用MAC地址:") for mac in macs: print(mac)
这个方案代码更简洁,可读性更强,适合快速开发。你可以根据自己的场景选择:追求无依赖选方案一,追求代码简洁选方案二。
内容的提问来源于stack exchange,提问作者frank hk
相关产品推荐
相关产品推荐

