如何通过Win32 API获取物理网络适配器信息?
获取物理网络适配器的Win32 API解决方案
核心结论
Win32 API完全可以实现类似Get-NetAdapter -Physical的功能,你可以通过挖掘IP_ADAPTER_ADDRESSES的隐藏信息,或者结合SetupAPI/CfgMgr32系列函数来获取物理适配器的详细数据。
方法一:从IP_ADAPTER_ADDRESSES中识别物理适配器
IP_ADAPTER_ADDRESSES并非没有物理适配器信息,只是需要针对性提取:
- MAC地址:结构体的
PhysicalAddress字段直接存储网卡的物理地址(MAC),长度由PhysicalAddressLength指定,这是物理适配器的核心标识。 - 判断物理类型:通过
IfType字段区分物理/虚拟适配器:- 有线物理网卡:
IfType = IF_TYPE_ETHERNET_CSMACD(数值6) - 无线物理网卡:
IfType = IF_TYPE_IEEE80211(数值71) - 虚拟适配器(如VPN、回环网卡)的
IfType通常为其他值(比如回环是IF_TYPE_SOFTWARE_LOOPBACK(24)、隧道是IF_TYPE_TUNNEL(131))
- 有线物理网卡:
方法二:结合SetupAPI获取完整物理设备信息
如果需要更详细的硬件属性(如设备名称、硬件ID、厂商信息),可以将IP_ADAPTER_ADDRESSES的AdapterName(设备实例ID)与SetupAPI结合:
- 调用
SetupDiGetClassDevs,传入GUID_DEVCLASS_NET枚举所有已安装的网络设备; - 遍历设备,用
SetupDiEnumDeviceInfo获取每个设备的SP_DEVINFO_DATA; - 通过
CM_Get_Device_ID获取设备实例ID,与IP_ADAPTER_ADDRESSES的AdapterName匹配; - 调用
SetupDiGetDeviceRegistryProperty读取设备属性,比如:SPDRP_FRIENDLYNAME:网卡友好名称(和PowerShell显示的一致)SPDRP_HARDWAREID:硬件ID,用于识别物理设备型号SPDRP_CAPABILITIES:检查CM_DEVCAP_VIRTUAL_DEVICE标记,排除虚拟设备
示例伪代码
#include <windows.h> #include <setupapi.h> #include <initguid.h> #include <devguid.h> void EnumPhysicalNetworkAdapters() { HDEVINFO hDevInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT | DIGCF_PROFILE); if (hDevInfo == INVALID_HANDLE_VALUE) return; SP_DEVINFO_DATA devInfoData = { sizeof(SP_DEVINFO_DATA) }; for (DWORD idx = 0; SetupDiEnumDeviceInfo(hDevInfo, idx, &devInfoData); idx++) { // 获取设备实例ID TCHAR szDeviceID[MAX_PATH]; if (CM_Get_Device_ID(devInfoData.DevInst, szDeviceID, MAX_PATH, 0) != CR_SUCCESS) continue; // 检查是否为虚拟设备 DWORD dwCapabilities = 0; if (!SetupDiGetDeviceRegistryProperty(hDevInfo, &devInfoData, SPDRP_CAPABILITIES, NULL, (PBYTE)&dwCapabilities, sizeof(dwCapabilities), NULL)) continue; if (dwCapabilities & CM_DEVCAP_VIRTUAL_DEVICE) continue; // 获取友好名称 TCHAR szFriendlyName[MAX_PATH]; if (SetupDiGetDeviceRegistryProperty(hDevInfo, &devInfoData, SPDRP_FRIENDLYNAME, NULL, (PBYTE)szFriendlyName, sizeof(szFriendlyName), NULL)) { // szFriendlyName 就是物理网卡的名称,可与GetAdaptersAddresses的FriendlyName匹配 } } SetupDiDestroyDeviceInfoList(hDevInfo); }
方法三:直接使用CfgMgr32函数筛选物理设备
如果你不需要IP相关信息,仅需枚举物理网卡硬件,可直接用CfgMgr32系列函数:
- 调用
CM_Get_Device_Interface_List枚举网络设备接口; - 对每个接口,用
CM_Get_Device_Interface_Detail获取设备实例; - 通过
CM_Get_DevNode_Status判断设备是否为物理存在的设备。
内容的提问来源于stack exchange,提问作者user3829872
相关产品推荐
相关产品推荐

