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

yizhihongxing

下面是关于“易语言调用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日

相关文章

  • JavaScript前端静态资源预加载实现示例

    JavaScript前端静态资源预加载是优化页面性能的一个关键策略之一。因为在实际网站开发中,网页所需要加载的资源(例如图片、CSS、JS文件等)往往体积较大,而静态资源预加载可以让用户在进入网站后,较快地获取到网站的内容。接下来,本篇文章将详细讲解如何实现JavaScript前端静态资源预加载。 1. 什么是静态资源预加载? 静态资源预加载是通过预先加载页…

    other 2023年6月25日
    00
  • mysql “group by”与”order by”的研究--分类中最新的内容

    MySQL “GROUP BY” 与 “ORDER BY” 的研究 – 分类中最新的内容 GROUP BY GROUP BY 运算符用于将相同的数据按照指定的列进行分组。在这个过程中,会自动生成一个分组的索引。结果集将按照索引的顺序进行排序输出。 语法 SELECT column_name(s) FROM table_name WHERE condition…

    other 2023年6月26日
    00
  • ArcGIS怎么修改属性表字段名称

    ArcGIS是一款专业的地理信息系统软件,属性表是ArcGIS中一个很重要的组成部分,它存储了地理数据的各种属性信息,包括字段名称、数据类型、值等等。在ArcGIS中修改属性表字段名称,可以通过以下步骤实现: 1. 打开属性表 首先,需要打开需要修改字段名称的图层的属性表。可以通过“图层属性”中的“打开属性表”按钮或者在图层上右键点击后选择“打开属性表”来打…

    other 2023年6月25日
    00
  • Maven一键部署Springboot到Docker仓库为自动化做准备(推荐)

    下面是详细讲解Maven一键部署Springboot到Docker仓库为自动化做准备的完整攻略。 一、前提条件 在开始使用Maven一键部署Springboot到Docker仓库之前,需要确保以下条件都满足: 1.已安装Docker,并正确配置了Docker环境; 2.已安装Maven,并正确配置了Maven环境; 3.已有一个可部署的Springboot项…

    other 2023年6月27日
    00
  • 逆水寒九灵什么属性重要 基本属性对九灵加成数据测试介绍

    当然,下面是关于逆水寒九灵基本属性加成数据测试的完整攻略,包含两个示例说明: 基本属性对九灵加成数据测试介绍 首先,选择一个九灵,例如「风灵」作为测试对象。 确定九灵的基本属性,包括攻击力、防御力、生命值等。 创建一个测试角色,并记录下其基本属性。 使用测试角色攻击一个固定的目标,记录下造成的伤害。 将测试角色装备上九灵「风灵」,并记录下装备后的基本属性。 …

    other 2023年10月17日
    00
  • iml文件

    以下是详细讲解“iml文件的完整攻略”的标准Markdown格式文本: iml文件的完整攻略 iml文件是IntelliJ IDEA项目的模块文件,包含了模块的配置信息。本文将介绍iml文件的基本概念、使用方法和两个示例说明。 1. iml文件基本概念 iml文件是IntelliJ IDEA项目的模块文件,包含了模块的配置信息。iml文件通常包含以下信息: …

    other 2023年5月10日
    00
  • 灵科静态与动态路由器的简介

    灵科静态与动态路由器的简介 灵科是一家网络设备供应商,其路由器产品的静态与动态路由功能可以帮助用户快速搭建网络并进行灵活的网络管理。 静态路由器 静态路由器是一种基于固定路由表的路由器,它通过添加和删除固定路由表条目来确定数据包的转发路径。该类型路由器的优点是简单易用、低耗能,同时也避免了复杂的网络环境下出现的路由环路问题。 示例: 假设我们有一个局域网,其…

    other 2023年6月27日
    00
  • 深入理解java中this关键字的使用

    深入理解Java中this关键字的使用 在Java中,this关键字用于引用当前对象。它可以在类的方法和构造函数中使用,用于区分实例变量和局部变量之间的冲突,以及在方法内部访问当前对象的成员。 1. 引用实例变量 当一个类中存在与方法参数同名的实例变量时,可以使用this关键字来引用实例变量。这样可以明确地指示使用的是实例变量而不是方法参数。 public …

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