首页 > 解决方案 > 在不使用 WMI 的情况下获取所有网络适配器的 MAC 地址

问题描述

使用 WMI 可以获得所有网络适配器 ( Win32_NetworkAdapter) 的列表,甚至是禁用的(因为NetworkInterface.GetAllNetworkInterfaces只返回启用的)。但是,某些系统禁用了 WMI,因此并不总是可用。我一直在查看 winapi 文档,但找不到一个可以返回所有文档的函数。是否存在这样的功能(以及哪一个)?我不想解析netsh。

标签: c#windowswinapinetworking

解决方案


这是来自 MSDN 的打印所有信息的示例。

//
// ConsoleApplication1.cpp : This file contains the 'main' function. Program execution begins and ends there.
//

#include "pch.h"

#include <winsock2.h>
#include <iphlpapi.h>
#include <stdio.h>
#pragma comment(lib, "IPHLPAPI.lib")
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))


/* Note: could also use malloc() and free() */


int __cdecl main(int argc, char **argv)
{
        /* Declare and initialize variables */

        DWORD dwSize = 0;
    DWORD dwRetVal = 0;

    unsigned int i = 0;

    // Set the flags to pass to GetAdaptersAddresses
    ULONG flags = GAA_FLAG_INCLUDE_PREFIX;

    // default to unspecified address family (both)
    ULONG family = AF_UNSPEC;

    LPVOID lpMsgBuf = NULL;

    PIP_ADAPTER_ADDRESSES pAddresses = NULL;
    ULONG outBufLen = 0;

    PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
    PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
    PIP_ADAPTER_ANYCAST_ADDRESS pAnycast = NULL;
    PIP_ADAPTER_MULTICAST_ADDRESS pMulticast = NULL;
    IP_ADAPTER_DNS_SERVER_ADDRESS *pDnServer = NULL;
    IP_ADAPTER_PREFIX *pPrefix = NULL;

    //if (argc != 2) {
    //    printf(" Usage: getadapteraddresses family\n");
    //    printf("        getadapteraddresses 4 (for IPv4)\n");
    //    printf("        getadapteraddresses 6 (for IPv6)\n");
    //    printf("        getadapteraddresses A (for both IPv4 and IPv6)\n");
    //    exit(1);
    //}

    //if (atoi(argv[1]) == 4)
    //    family = AF_INET;
    //else if (atoi(argv[1]) == 6)
    //    family = AF_INET6;

    outBufLen = sizeof(IP_ADAPTER_ADDRESSES);
    pAddresses = (IP_ADAPTER_ADDRESSES *)MALLOC(outBufLen);

    // Make an initial call to GetAdaptersAddresses to get the 
    // size needed into the outBufLen variable
    if (GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen)
        == ERROR_BUFFER_OVERFLOW) {
        FREE(pAddresses);
        pAddresses = (IP_ADAPTER_ADDRESSES *)MALLOC(outBufLen);
    }

    if (pAddresses == NULL) {
        printf("Memory allocation failed for IP_ADAPTER_ADDRESSES struct\n");
        exit(1);
    }
    // Make a second call to GetAdapters Addresses to get the
    // actual data we want
    printf("Memory allocated for GetAdapterAddresses = %d bytes\n", outBufLen);
    printf("Calling GetAdaptersAddresses function with family = ");
    if (family == AF_INET)
        printf("AF_INET\n");
    if (family == AF_INET6)
        printf("AF_INET6\n");
    if (family == AF_UNSPEC)
        printf("AF_UNSPEC\n\n");

    dwRetVal =
        GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen);

    if (dwRetVal == NO_ERROR) {
        // If successful, output some information from the data we received
        pCurrAddresses = pAddresses;
        while (pCurrAddresses) {
            printf("\tLength of the IP_ADAPTER_ADDRESS struct: %ld\n",
                pCurrAddresses -> Length);
            printf("\tIfIndex (IPv4 interface): %u\n", pCurrAddresses -> IfIndex);
            printf("\tAdapter name: %s\n", pCurrAddresses -> AdapterName);

            pUnicast = pCurrAddresses -> FirstUnicastAddress;
            if (pUnicast != NULL) {
                for (i = 0; pUnicast != NULL; i++)
                    pUnicast = pUnicast -> Next;
                printf("\tNumber of Unicast Addresses: %d\n", i);
            }
            else
                printf("\tNo Unicast Addresses\n");

            pAnycast = pCurrAddresses -> FirstAnycastAddress;
            if (pAnycast) {
                for (i = 0; pAnycast != NULL; i++)
                    pAnycast = pAnycast -> Next;
                printf("\tNumber of Anycast Addresses: %d\n", i);
            }
            else
                printf("\tNo Anycast Addresses\n");

            pMulticast = pCurrAddresses -> FirstMulticastAddress;
            if (pMulticast) {
                for (i = 0; pMulticast != NULL; i++)
                    pMulticast = pMulticast -> Next;
                printf("\tNumber of Multicast Addresses: %d\n", i);
            }
            else
                printf("\tNo Multicast Addresses\n");

            pDnServer = pCurrAddresses -> FirstDnsServerAddress;
            if (pDnServer) {
                for (i = 0; pDnServer != NULL; i++)
                    pDnServer = pDnServer -> Next;
                printf("\tNumber of DNS Server Addresses: %d\n", i);
            }
            else
                printf("\tNo DNS Server Addresses\n");

            printf("\tDNS Suffix: %wS\n", pCurrAddresses -> DnsSuffix);
            printf("\tDescription: %wS\n", pCurrAddresses -> Description);
            printf("\tFriendly name: %wS\n", pCurrAddresses -> FriendlyName);

            if (pCurrAddresses -> PhysicalAddressLength != 0) {
                printf("\tPhysical address: ");
                for (i = 0; i < pCurrAddresses -> PhysicalAddressLength;
                    i++) {
                    if (i == (pCurrAddresses -> PhysicalAddressLength - 1))
                        printf("%.2X\n",
                        (int)pCurrAddresses -> PhysicalAddress[i]);
                    else
                        printf("%.2X-",
                        (int)pCurrAddresses -> PhysicalAddress[i]);
                }
            }
            printf("\tFlags: %ld\n", pCurrAddresses -> Flags);
            printf("\tMtu: %lu\n", pCurrAddresses -> Mtu);
            printf("\tIfType: %ld\n", pCurrAddresses -> IfType);
            printf("\tOperStatus: %ld\n", pCurrAddresses -> OperStatus);
            printf("\tIpv6IfIndex (IPv6 interface): %u\n",
                pCurrAddresses -> Ipv6IfIndex);
            printf("\tZoneIndices (hex): ");
            for (i = 0; i < 16; i++)
                printf("%lx ", pCurrAddresses -> ZoneIndices[i]);
            printf("\n");

            pPrefix = pCurrAddresses -> FirstPrefix;
            if (pPrefix) {
                for (i = 0; pPrefix != NULL; i++)
                    pPrefix = pPrefix -> Next;
                printf("\tNumber of IP Adapter Prefix entries: %d\n", i);
            }
            else
                printf("\tNo IP Adapter Prefix entries\n");

            printf("\n");

            pCurrAddresses = pCurrAddresses -> Next;
        }
    }
    else {
        printf("Call to GetAdaptersAddresses failed with error: %d\n",
            dwRetVal);
        if (dwRetVal == ERROR_NO_DATA)
            printf("\tNo addresses were found for the requested parameters\n");
        else {

            if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwRetVal, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),   // Default language
                (LPTSTR) &lpMsgBuf, 0, NULL)) {
                printf("\tError: %s", (LPSTR)lpMsgBuf);
                LocalFree(lpMsgBuf);
                FREE(pAddresses);
                exit(1);
            }
        }
    }
    FREE(pAddresses);
    return 0;

}

推荐阅读