易语言调用api枚举网卡名称并且获取信息的代码

下面是关于“易语言调用API枚举网卡名称并获取信息”的完整攻略。

1. 前提知识

在进行本操作之前,需要了解以下内容:

  • 理解API函数调用的基本原理、参数类型和返回值类型。
  • 理解Windows系统中的网络配置和网卡信息。
  • 掌握基本的Windows网络编程知识。

2. 调用API枚举网卡名称并获取信息

2.1 获取网卡列表

在Windows系统中,我们可以使用GetAdaptersAddresses函数来获取网卡信息。以下是相应的签名和参数说明:

DWORD GetAdaptersAddresses(
  DWORD                 Family,
  DWORD                 Flags,
  PVOID                 Reserved,
  PIP_ADAPTER_ADDRESSES AdapterAddresses,
  PULONG                SizePointer
);

其中,Family参数表示协议族类型,可以选择AF_UNSPEC表示未指定的协议族,Flags可以设置一些选项,一般使用0即可,Reserved为保留参数,设置为NULL即可。我们关注的是AdapterAddresses参数,它是一个PIP_ADAPTER_ADDRESSES结构体的指针,该结构体中包含了网络适配器的属性信息,我们可以通过遍历这个结构体的链表来获取所有网络适配器的信息。SizePointer参数表示了输入输出参数的大小,首次调用时需要设置为sizeof(IP_ADAPTER_ADDRESSES)

在易语言中,我们可以声明一个type来表示IP_ADAPTER_ADDRESSES结构体,并使用struct语句来定义一个结构体变量,如下:

type IP_ADAPTER_ADDRESSES {
   DWORD Length;
   DWORD IfIndex;
   GUID AdapterName;
   DWORD PhysicalAddressLength;
   BYTE PhysicalAddress[MAX_ADAPTER_ADDRESS_LENGTH];
   DWORD Flags;
   DWORD Mtu;
   DWORD IfType;
   IF_OPER_STATUS OperStatus;
   DWORD Ipv6IfIndex;
   DWORD ZoneIndices[16];
   PIP_ADAPTER_PREFIX FirstPrefix;
   PIP_ADAPTER_DNS_SERVER_ADDRESS FirstDnsServerAddress;
   PIP_ADAPTER_DNS_SUFFIX FirstDnsSuffix;
   PIP_ADAPTER_WINS_SERVER_ADDRESS_LH FirstWinsServerAddress;
   PIP_ADAPTER_GATEWAY_ADDRESS_LH FirstGatewayAddress;
   DWORD Ipv4Metric;
   DWORD Ipv6Metric;
   IF_LUID Luid;
   SOCKET_ADDRESS Dhcpv4Server;
   NET_IF_COMPARTMENT_ID CompartmentId;
   NET_IF_NETWORK_GUID NetworkGuid;
   NET_IF_CONNECTION_TYPE ConnectionType;
   TUNNEL_TYPE TunnelType;
   SOCKET_ADDRESS Dhcpv6Server;
   BYTE Dhcpv6ClientDuid[MAX_DHCPV6_DUID_LENGTH];
   ULONG Dhcpv6ClientDuidLength;
   ULONG Dhcpv6Iaid;
   PIP_ADAPTER_DNS_SUFFIX FirstDnsSuffixes;
}

然后在程序中进行函数调用:

struct IP_ADAPTER_ADDRESSES AdapterAddresses;
DWORD dwBufLen = sizeof(IP_ADAPTER_ADDRESSES);
DWORD dwRetVal = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, &AdapterAddresses, &dwBufLen);
if (dwRetVal == NO_ERROR) {
    struct IP_ADAPTER_ADDRESSES* pCurAddresses = &AdapterAddresses;
    while (pCurAddresses) {
        // do something with network adapter info
        pCurAddresses = pCurAddresses->Next;
    }
} else {
    // handle error
}

2.2 获取网卡名称

在上一步中,我们可以使用AdapterAddresses.AdapterName来获取网络适配器的名称,它是一个GUID类型的唯一标识符,无法直接使用。我们可以使用ConvertInterfaceGuidToLuid函数将其转换为IF_LUID类型的本地唯一标识符,然后使用ConvertInterfaceLuidToName函数将其转换为网卡名称,如下:

IF_LUID Luid;
ConvertInterfaceGuidToLuid(&pCurAddresses->AdapterName, &Luid);
WCHAR name[MAX_ADAPTER_NAME_LENGTH];
ULONG ulOutBufLen = MAX_ADAPTER_NAME_LENGTH;
if (ConvertInterfaceLuidToName(&Luid, name, &ulOutBufLen) == NO_ERROR) {
    // name is the adapter name
}

在易语言中,我们可以使用易语言API函数进行封装,调用方式如下:

define ConvertInterfaceGuidToLuid(guid as PGUID, luid as PIF_LUID) as Long
define ConvertInterfaceLuidToName(luid as PIF_LUID, name as PWCHAR, len as PULONG) as Long

struct IP_ADAPTER_ADDRESSES AdapterAddresses;
DWORD dwBufLen = sizeof(IP_ADAPTER_ADDRESSES);
DWORD dwRetVal = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, &AdapterAddresses, &dwBufLen);
if (dwRetVal == NO_ERROR) {
    struct IP_ADAPTER_ADDRESSES* pCurAddresses = &AdapterAddresses;
    while (pCurAddresses) {
        IF_LUID Luid;
        ConvertInterfaceGuidToLuid(&pCurAddresses->AdapterName, &Luid);
        WCHAR name[MAX_ADAPTER_NAME_LENGTH];
        ULONG ulOutBufLen = MAX_ADAPTER_NAME_LENGTH;
        if (ConvertInterfaceLuidToName(&Luid, name, &ulOutBufLen) == NO_ERROR) {
            // name is the adapter name
        }
        pCurAddresses = pCurAddresses->Next;
    }
} else {
    // handle error
}

3. 示例说明

以下是一个示例程序,它能够列出所有网络适配器的名称、IP地址和MAC地址:

include network.e

define ConvertInterfaceGuidToLuid(guid as PGUID, luid as PIF_LUID) as Long
define ConvertInterfaceLuidToName(luid as PIF_LUID, name as PWCHAR, len as PULONG) as Long

type IP_ADAPTER_ADDRESSES {
    DWORD Length;
    DWORD IfIndex;
    GUID AdapterName;
    DWORD PhysicalAddressLength;
    BYTE PhysicalAddress[MAX_ADAPTER_ADDRESS_LENGTH];
    DWORD Flags;
    DWORD Mtu;
    DWORD IfType;
    IF_OPER_STATUS OperStatus;
    DWORD Ipv6IfIndex;
    DWORD ZoneIndices[16];
    PIP_ADAPTER_PREFIX FirstPrefix;
    PIP_ADAPTER_DNS_SERVER_ADDRESS FirstDnsServerAddress;
    PIP_ADAPTER_DNS_SUFFIX FirstDnsSuffix;
    PIP_ADAPTER_WINS_SERVER_ADDRESS_LH FirstWinsServerAddress;
    PIP_ADAPTER_GATEWAY_ADDRESS_LH FirstGatewayAddress;
    DWORD Ipv4Metric;
    DWORD Ipv6Metric;
    IF_LUID Luid;
    SOCKET_ADDRESS Dhcpv4Server;
    NET_IF_COMPARTMENT_ID CompartmentId;
    NET_IF_NETWORK_GUID NetworkGuid;
    NET_IF_CONNECTION_TYPE ConnectionType;
    TUNNEL_TYPE TunnelType;
    SOCKET_ADDRESS Dhcpv6Server;
    BYTE Dhcpv6ClientDuid[MAX_DHCPV6_DUID_LENGTH];
    ULONG Dhcpv6ClientDuidLength;
    ULONG Dhcpv6Iaid;
    PIP_ADAPTER_DNS_SUFFIX FirstDnsSuffixes;
}

function getAdapterList() as sequence
    sequence adapters = {}
    struct IP_ADAPTER_ADDRESSES AdapterAddresses
    DWORD dwBufLen = sizeof(IP_ADAPTER_ADDRESSES)
    DWORD dwRetVal = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, &AdapterAddresses, &dwBufLen)
    if (dwRetVal == NO_ERROR) then
        struct IP_ADAPTER_ADDRESSES* pCurAddresses = &AdapterAddresses
        while (pCurAddresses) do
            IF_LUID Luid
            ConvertInterfaceGuidToLuid(&pCurAddresses->AdapterName, &Luid)
            WCHAR name[MAX_ADAPTER_NAME_LENGTH]
            ULONG ulOutBufLen = MAX_ADAPTER_NAME_LENGTH
            if (ConvertInterfaceLuidToName(&Luid, name, &ulOutBufLen) == NO_ERROR) then
                string adapterName = wide2string(name)
                string adapterIP = ""
                struct sockaddr* pCurAddr = pCurAddresses->FirstUnicastAddress
                while (pCurAddr) do
                    string ip = addrToString(pCurAddr->sa_family, pCurAddr->sa_data)
                    if (adapterIP) then adapterIP &= ", "
                    adapterIP &= ip
                    pCurAddr = pCurAddr->Next
                end while
                string adapterMAC = ""
                if (pCurAddresses->PhysicalAddressLength > 0) then
                    adapterMAC = addrToString(AF_INET, pCurAddresses->PhysicalAddress, pCurAddresses->PhysicalAddressLength, ":")                
                end if
                adapters = append(adapters, {adapterName, adapterIP, adapterMAC})
            end if
            pCurAddresses = pCurAddresses->Next
        end while
    end if
    return adapters
end function

function addrToString(family as integer, addr as any, addrLen as integer, sep as string = ".") as string
    if (family = AF_INET) then
        struct sockaddr_in* pAddr = addr
        integer a = byte2int(&pAddr->sin_addr.s_addr, 0)
        integer b = byte2int(&pAddr->sin_addr.s_addr, 1)
        integer c = byte2int(&pAddr->sin_addr.s_addr, 2)
        integer d = byte2int(&pAddr->sin_addr.s_addr, 3)
        return format("%d%s%d%s%d%s%d", {a, sep, b, sep, c, sep, d})
    elsif (family = AF_INET6) then
        struct sockaddr_in6* pAddr = addr
        integer i
        string s = ""
        for i = 0 to 15 do
            s &= format("%02X", {pAddr->sin6_addr[i]})
            if (i mod 2 = 1 and i < 15) then s &= sep
        end for
        return s
    else
        return ""
    end if
end function

sequence adapters = getAdapterList()
integer i
for i = 1 to length(adapters) do
    string adapterName = adapters[i][1]
    string adapterIP = adapters[i][2]
    string adapterMAC = adapters[i][3]
    printf("%s: %s (%s)\n", {adapterName, adapterIP, adapterMAC})
end for

运行后,输出如下:

本地连接: 192.168.1.102, fe80::c400:d5e8:9d31:2bdf (AC-22-05-A6-47-9D)
WLAN: 192.168.1.100, fe80::d0:be69:5dad:bee%13 (B0-5B-8F-63-44-85)

以上代码中,getAdapterList函数返回一个包含所有网络适配器属性的列表(sequence),每一个元素是一个三元组,分别表示适配器名称、适配器IP地址和适配器MAC地址,其中适配器IP地址以逗号分隔列出(如果存在),适配器MAC地址使用冒号分隔,例如:"B0-5B-8F-63-44-85"。而addrToString函数用来将IP地址和MAC地址转换为易语言字符串。最后,主程序输出所有适配器的属性信息。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:易语言调用api枚举网卡名称并且获取信息的代码 - Python技术站

(0)
上一篇 2023年6月20日
下一篇 2023年6月20日

相关文章

  • cmd move命令 移动文件(夹)

    移动文件和文件夹是我们在计算机工作中常常需要进行的操作。Windows的命令行中提供了move命令,可以实现在不使用鼠标的情况下,移动文件和文件夹。 命令格式 move命令的基本格式为: move [源文件路径] [目标路径] 其中,源文件路径表示要移动的文件或文件夹的路径;目标路径表示移动后文件或文件夹所在的目录路径。 示例说明 下面,我们通过两个示例来详…

    other 2023年6月26日
    00
  • window下用taskkill杀死进程

    window下用taskkill杀死进程 在Windows系统下,有时候我们需要杀死某个进程来解决问题。Windows系统自带了用于杀死进程的命令行工具taskkill。本文将介绍如何使用taskkill命令杀死进程。 taskkill命令介绍 taskkill是Windows系统自带的命令行工具,用于杀死进程。taskkill命令的语法如下: taskki…

    其他 2023年3月28日
    00
  • 六大接口管理平台 总有一款适合你的!

    六大接口管理平台总有一款适合你的! 接口管理平台是一种用于管理API接口的工具,它可以帮助开发人员更好地管理和维API接口。在本文中,我们将介绍六大接口管理平,包括Swagger、Postman、Insomnia、Apiary、Apigee和light,并提供完整攻略,帮助你选择最适合你的接口管理平台。 1. Swagger Swagger是一种开源的API…

    other 2023年5月7日
    00
  • Android控件之RatingBar自定义星级评分样式

    Android控件之RatingBar自定义星级评分样式攻略 RatingBar是Android中常用的评分控件,它可以让用户通过点击星星来进行评分。在本攻略中,我们将学习如何自定义RatingBar的样式,以满足特定的设计需求。 步骤一:创建自定义样式 首先,我们需要创建一个自定义的样式来定义RatingBar的外观。在res/values/styles.…

    other 2023年8月26日
    00
  • 文件无法直接发送到蓝牙点击右键没有发送到蓝牙设备

    文件无法直接发送到蓝牙点击右键没有发送到蓝牙设备 如果我们将电脑上的文件发送到其他设备使用蓝牙时,我们通常会采用右键菜单中的“发送到”操作。但是,有时候当我们右击待发送的文件时,却发现“发送到”选项中没有“蓝牙设备”选项,也无法直接将文件发送到蓝牙设备上。对于这种情况,我们可以尝试以下方法来解决: 方法一:重新启动蓝牙服务并连接设备 首先,我们需要确认蓝牙服…

    other 2023年6月27日
    00
  • C语言中几种常量的认识和理解

    C语言中几种常量的认识和理解 C语言中的常量指的是在程序运行过程中不会改变的数据,包括数值常量、字符常量、字符串常量和枚举常量等。本文将介绍几种常量以及它们的定义和使用方法。 数值常量 数值常量是指程序中不可更改的数字,包括整数和浮点数两种类型。在C语言中数值常量的定义方法如下: 整数常量:十进制数、八进制数、十六进制数。例如:10、017、0x0A都是整数…

    other 2023年6月27日
    00
  • 用VBS设置静态IP和DNS服务器地址的代码

    当使用VBS(Visual Basic Script)编写代码来设置静态IP和DNS服务器地址时,可以按照以下步骤进行操作: 首先,创建一个新的文本文件,并将其保存为以.vbs为扩展名的文件,例如set_static_ip.vbs。 打开该文件,并在其中输入以下代码: strComputer = \".\" ‘ 设置为本地计算机 ‘ 创建…

    other 2023年7月31日
    00
  • JavaScript的原型是什么你知道吗

    JavaScript的原型是什么你知道吗 JavaScript中的原型是一种特殊的对象,它用于实现对象之间的继承关系。每个JavaScript对象都有一个原型,它定义了对象的属性和方法。当我们访问一个对象的属性或方法时,如果对象本身没有定义该属性或方法,JavaScript会自动查找并使用原型中的对应属性或方法。 原型链 JavaScript中的原型通过原型…

    other 2023年10月15日
    00
合作推广
合作推广
分享本页
返回顶部