因此,我试图为此寻找几个不同的答案。我认为可以保证的一个就是:

How to check network interface type is Ethernet or Wireless on Windows using Qt?

但是,我对网络甚至Windows并不太了解。我个人无法理解其网站上的大多数Microsoft文档。我已经尝试过诸如INetworkConnectionNativeWiFi等之类的东西,但是它们要么不执行我想要的操作,要么无法从可用的文档中弄清楚该如何做。

话虽如此,我想使用C++来检查正在运行此程序的设备是否通过以太网电缆连接到Internet。基本上,我想执行以下操作:

  • 如果计算机仅连接到无线,请运行程序
  • 如果计算机仅连接到“有线”,则不要运行程序
  • 如果计算机同时连接到有线和无线,请不要运行
  • 程序

    但是,问题是我不知道如何检查设备是否连接了以太网。有没有办法做到这一点?我没有使用QT。谢谢!

    编辑:我还应该包括到目前为止已经尝试过的内容。

    我尝试使用GetAdaptersInfo并从Type变量类型中获取PIP_ADAPTER_INFO特性,但是无论我是否在以太网上,这总是给我Unknown type 71

    GetAdaptersInfo的文档在这里:
    https://msdn.microsoft.com/en-us/library/aa365917%28VS.85%29.aspx

    谢谢

    编辑2:这是我用于GetAdaptersInfo的代码
    bool is_on_ethernet{
        PIP_ADAPTER_INFO pAdapterInfo;
        PIP_ADAPTER_INFO pAdapter = NULL;
        DWORD dwRetVal = 0;
        UINT i;
    
        struct tm newtime;
        char buffer[32];
        errno_t error;
    
        ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
        pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO));
    
        if(pAdapterInfo == NULL)
            printf("Error allocating memory need to call GetAdaptersInfo");
    
        if(GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW){
            free(pAdapterInfo);
            pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen);
        }
    
        if((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR){
            pAdapter = pAdapterInfo;
    
            switch(pAdapter->Type){
                case MIB_IF_TYPE_OTHER:
                    printf("Other\n");
                    return false;
                    break;
                case MIB_IF_TYPE_ETHERNET:
                    printf("Ethernet\h");
                    return true;
                    break;
                case MIB_IF_TYPE_TOKENRING:
                    printf("Token Ring\n");
                    return false;
                    break;
                case MIB_IF_TYPE_FDDI
                    printf("FDDI\n");
                    return false;
                    break;
                case MIB_IF_TYPE_PPP
                    printf("PPP\n");
                    return false;
                    break;
                case MIB_IF_TYPE_LOOPBACK
                    printf("Lookback\n");
                    return false;
                    break;
                case MIB_IF_TYPE_SLIP
                    printf("Slip\n");
                    return false;
                    break;
                default
                    printf("Unknown type %ld\n\n", pAdapter->Type);
                    return false;
                    break;
            }
        }
    
        if(pAdapterInfo)
            free(pAdapterInfo);
    
        return false;
    }
    

    最佳答案

    您的问题有些困难,因为要获得“当前”网络适配器会非常复杂-Windows根据网络适配器配置和目标可达性来路由数据包,因此您的“当前”适配器可能随时更改...但是由于您您已经知道如何检索可用适配器的IP和MAC(“硬件地址”),您可以简单地使用黑客为您当前的IP检索MAC,并在我的第二个功能内进行过滤/搜索!您正在寻找“PhysicalAddress”字段,这就是MAC地址

    我的经验是,唯一可行的方法是通过GetIfTableGetIfTable2,前者返回superficial adpater info,而后者提供了很好的detail
    这是一个示例实现,因为它使用了详细功能,您也可以查询WLAN适配器:

    vector<MIB_IF_ROW2>* getDevices(NDIS_PHYSICAL_MEDIUM type)
        {
            vector<MIB_IF_ROW2> *v = new vector<MIB_IF_ROW2>();
            PMIB_IF_TABLE2 table = NULL;
            if(GetIfTable2Ex(MibIfTableRaw, &table) == NOERROR && table)
            {
                UINT32 i = 0;
                for(; i < table->NumEntries; i++)
                {
                    MIB_IF_ROW2 row;
    
                    ZeroMemory(&row, sizeof(MIB_IF_ROW2));
                    row.InterfaceIndex = i;
                    if(GetIfEntry2(&row) == NOERROR)
                    {
                        if(row.PhysicalMediumType == type)
                        {
                            v->push_back(row);
                        }
                    }
                }
                FreeMibTable(table);
            }
            return v;
        }
    

    现在,您需要做的就是遍历列表,并过滤掉禁用的适配器以及诸如此类的东西:
    vector<MIB_IF_ROW2>* wlan = getDevices(NdisPhysicalMediumNative802_11); //WLAN adapters
    //see https://msdn.microsoft.com/en-us/library/windows/desktop/aa814491(v=vs.85).aspx, "PhysicalMediumType" for a full list
    for(auto &row : *v)
        {
            //do some additional filtering, this needs to be changed for non-WLAN
            if( row.TunnelType == TUNNEL_TYPE_NONE &&
                row.AccessType != NET_IF_ACCESS_LOOPBACK &&
                row.Type == IF_TYPE_IEEE80211 &&
                row.InterfaceAndOperStatusFlags.HardwareInterface == TRUE)
                {
                    //HERE BE DRAGONS!
                }
        }
    

    现在,它很容易生成WLAN适配器和非WLAN适配器的列表(请参阅第二个功能中的注释),搜索当前的MAC并得出结论,它是有线的还是无线的-但请注意,这些列表可能与重叠,因为802.11基本上是802.3 的扩展版本,但 802.3是否不包括802.11t(因为它是扩展名),因此您将需要一点if/else逻辑,以便将WLAN与非WLAN适配器分开。

    您还可以使用WlanEnumInterfaces来获取所有WLAN适配器,但是那基本上与使用上面以NdisPhysicalMediumNative802_11作为参数的功能相同...

    09-13 04:47