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

如何在Qt中编程获取网络管理器设备名?Windows下Qt/C++如何获取网卡描述?

在Windows下用Qt/C++识别USB以太网适配器

嘿,我来帮你搞定这个问题!你已经用到了QNetworkInterface的humanReadableName(),其实这个方法在Windows系统上通常返回的就是设备管理器里的网络适配器描述(比如“USB Ethernet Adapter”),但如果要更精准地识别USB类型的适配器,或者遇到名称里没有明显“USB”标识的情况,咱们可以结合Windows原生API来获取更底层的硬件信息。

方法一:纯Qt快速判断

先优化你现有的代码,加上过滤和更详细的打印信息,直接通过可读名称判断是否为USB适配器:

#include <QCoreApplication>
#include <QNetworkInterface>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 获取所有网络接口
    QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces();
    for (const QNetworkInterface& iface : interfaces) {
        // 跳过未启用的接口(可选)
        if (!(iface.flags() & QNetworkInterface::IsUp)) {
            continue;
        }

        qDebug() << "\n=== 接口" << interfaces.indexOf(iface) << "信息 ===";
        qDebug() << "设备描述(可读名称):" << iface.humanReadableName();
        qDebug() << "系统接口名称:" << iface.name();
        qDebug() << "硬件地址:" << iface.hardwareAddress();
        // 模糊匹配判断是否为USB适配器
        bool isUsbAdapter = iface.humanReadableName().contains("USB", Qt::CaseInsensitive);
        qDebug() << "是否为USB以太网适配器:" << (isUsbAdapter ? "✅ 是" : "❌ 否");
    }

    return a.exec();
}

这个方法简单直接,适合大部分场景,但如果有些USB适配器的名称里没有“USB”字样,就需要用下面的方法。

方法二:结合Windows原生API精准识别

如果要百分百准确判断,咱们可以调用Windows的SetupDi系列API和GetAdaptersAddresses,获取适配器的硬件ID(硬件ID里一定会包含USB相关标识),代码如下:

#include <QCoreApplication>
#include <QNetworkInterface>
#include <QDebug>
#include <Windows.h>
#include <SetupAPI.h>
#include <IPHlpApi.h>
#include <devguid.h>

// 链接Windows所需的库
#pragma comment(lib, "setupapi.lib")
#pragma comment(lib, "iphlpapi.lib")

// 获取所有网络适配器的设备详情(含USB判断)
void getNetworkAdapterDeviceDetails() {
    ULONG bufferSize = 0;
    // 先调用一次获取缓冲区大小
    GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, NULL, &bufferSize);
    PIP_ADAPTER_ADDRESSES pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(bufferSize);
    if (!pAddresses) {
        qDebug() << "内存分配失败!";
        return;
    }

    if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &bufferSize) != NO_ERROR) {
        qDebug() << "获取适配器地址失败!";
        free(pAddresses);
        return;
    }

    // 遍历每个适配器
    for (PIP_ADAPTER_ADDRESSES pCurr = pAddresses; pCurr; pCurr = pCurr->Next) {
        // 只处理以太网和无线网卡(可选)
        if (pCurr->IfType != IF_TYPE_ETHERNET_CSMACD && pCurr->IfType != IF_TYPE_IEEE80211) {
            continue;
        }

        // 打开网络设备信息集
        HDEVINFO hDevInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
        if (hDevInfo == INVALID_HANDLE_VALUE) {
            continue;
        }

        SP_DEVICE_INTERFACE_DATA ifaceData = {0};
        ifaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
        DWORD index = 0;
        bool foundAdapter = false;

        // 枚举所有网络设备接口
        while (SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &GUID_DEVCLASS_NET, index++, &ifaceData)) {
            // 获取设备详情所需的缓冲区大小
            DWORD detailSize = 0;
            SetupDiGetDeviceInterfaceDetail(hDevInfo, &ifaceData, NULL, 0, &detailSize, NULL);
            PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(detailSize);
            if (!pDetail) continue;
            pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

            SP_DEVINFO_DATA devInfo = {0};
            devInfo.cbSize = sizeof(SP_DEVINFO_DATA);

            if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &ifaceData, pDetail, detailSize, NULL, &devInfo)) {
                // 获取设备描述(优先友好名称,其次设备描述)
                TCHAR deviceDesc[MAX_PATH] = {0};
                if (!SetupDiGetDeviceRegistryProperty(hDevInfo, &devInfo, SPDRP_FRIENDLYNAME, NULL, (PBYTE)deviceDesc, sizeof(deviceDesc), NULL)) {
                    SetupDiGetDeviceRegistryProperty(hDevInfo, &devInfo, SPDRP_DEVICEDESC, NULL, (PBYTE)deviceDesc, sizeof(deviceDesc), NULL);
                }

                // 获取硬件ID
                TCHAR hardwareId[MAX_PATH] = {0};
                SetupDiGetDeviceRegistryProperty(hDevInfo, &devInfo, SPDRP_HARDWAREID, NULL, (PBYTE)hardwareId, sizeof(hardwareId), NULL);

                // 匹配适配器的设备实例ID
                if (wcscmp(pCurr->AdapterName, devInfo.DevInst) == 0) {
                    qDebug() << "\n=== 适配器详情 ===";
                    qDebug() << "设备描述:" << QString::fromWCharArray(deviceDesc);
                    qDebug() << "硬件ID:" << QString::fromWCharArray(hardwareId);
                    bool isUsb = QString::fromWCharArray(hardwareId).contains("USB", Qt::CaseInsensitive);
                    qDebug() << "是否为USB适配器:" << (isUsb ? "✅ 是" : "❌ 否");
                    foundAdapter = true;
                }
            }
            free(pDetail);
            if (foundAdapter) break;
        }
        SetupDiDestroyDeviceInfoList(hDevInfo);
    }
    free(pAddresses);
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    getNetworkAdapterDeviceDetails();
    return a.exec();
}

代码说明:

  1. 调用GetAdaptersAddresses获取系统所有网络适配器的基础信息,包括设备实例ID;
  2. 通过SetupDi系列API枚举网络设备,匹配对应的设备实例ID;
  3. 获取设备的硬件ID,硬件ID中包含设备的总线类型(比如USB设备的硬件ID会有USB\前缀),以此精准判断是否为USB适配器;
  4. 同时获取设备的友好名称/描述,和Qt的humanReadableName()对应。

内容的提问来源于stack exchange,提问作者A. Fasih

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:37:58