You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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结合:

  1. 调用SetupDiGetClassDevs,传入GUID_DEVCLASS_NET枚举所有已安装的网络设备;
  2. 遍历设备,用SetupDiEnumDeviceInfo获取每个设备的SP_DEVINFO_DATA;
  3. 通过CM_Get_Device_ID获取设备实例ID,与IP_ADAPTER_ADDRESSES的AdapterName匹配;
  4. 调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 08:44:52