在python中使用Win32 IPHelper API时出现问题

在python中使用Win32 IPHelper API时出现问题,python,windows,winapi,ctypes,iphelper,Python,Windows,Winapi,Ctypes,Iphelper,我正在尝试创建python模块来获取网络参数。我使用的是ctypes,有一些问题 函数_getInterfaces_win2k()适用于python 2.5和2.6,但不适用于python 2.7(python.exe中0x1e001759处未处理的异常:0xC0000005:访问冲突读取位置0x00000010) 函数uu getInterfaces_win_after_win2k()在任何版本的python中都不起作用(相同的错误) 有时,在崩溃程序之前打印必要的信息。我试着用C语言比较所有

我正在尝试创建python模块来获取网络参数。我使用的是ctypes,有一些问题

函数_getInterfaces_win2k()适用于python 2.5和2.6,但不适用于python 2.7(python.exe中0x1e001759处未处理的异常:0xC0000005:访问冲突读取位置0x00000010)

函数uu getInterfaces_win_after_win2k()在任何版本的python中都不起作用(相同的错误)

有时,在崩溃程序之前打印必要的信息。我试着用C语言比较所有的值,一切都正常。非常感谢您的帮助

'''
    Get different network parameters (interfaces, routing table, etc)
'''

from platform import system
from sys import getwindowsversion

def getInterfaces():
    if system() == 'Windows':
        winversion = getwindowsversion() 
        #from table on page OSVERSIONINFO Structure for GetVersionEx Function
        if winversion[0] > 5 or (winversion[0] == 5 and winversion[1] > 0):
            return __getInterfaces_win_after_win2k()
        else:
            return __getInterfaces_win2k()
    else:
        pass

MAX_ADAPTER_ADDRESS_LENGTH = 8

def __getInterfaces_win_after_win2k():
    import ctypes.wintypes

    class HEADER_STRUCT(ctypes.Structure):
        _fields_ = [
            ("Length", ctypes.c_ulong),
            ("IfIndex", ctypes.c_ulong)]

    class HEADER_UNION(ctypes.Union):
        _fields_ = [
            ("Alignment", ctypes.c_ulonglong),
            ("HEADER_STRUCT", HEADER_STRUCT)]

    class SOCKADDR(ctypes.Structure):
        _fields_ = [
            ("sa_family", ctypes.c_ushort),
            ("sa_data", ctypes.c_byte * 14)]
    PSOCKADDR = ctypes.POINTER(SOCKADDR)

    class SOCKET_ADDRESS(ctypes.Structure):
        _fields_ = [
            ("pSockaddr", PSOCKADDR),
            ("iSockaddrLength", ctypes.c_int)]

    class IP_ADAPTER_UNICAST_ADDRESS(ctypes.Structure):
        pass
    PIP_ADAPTER_UNICAST_ADDRESS = ctypes.POINTER(IP_ADAPTER_UNICAST_ADDRESS)
    IP_ADAPTER_UNICAST_ADDRESS._fields_ = [
        ("length", ctypes.c_ulong),
        ("flags", ctypes.c_ulong),
        ("next", PIP_ADAPTER_UNICAST_ADDRESS),
        ("address", SOCKET_ADDRESS),
        ("prefixOrigin", ctypes.c_int),
        ("suffixOrigin", ctypes.c_int),
        ("dadState", ctypes.c_int),
        ("validLifetime", ctypes.c_ulong),
        ("preferredLifetime", ctypes.c_ulong),
        ("leaseLifetime", ctypes.c_ulong),
        ("onLinkPrefixLength", ctypes.c_byte)]

    class IP_ADAPTER_ANYCAST_ADDRESS(ctypes.Structure):
        pass
    PIP_ADAPTER_ANYCAST_ADDRESS = ctypes.POINTER(IP_ADAPTER_ANYCAST_ADDRESS)
    IP_ADAPTER_ANYCAST_ADDRESS._fields_ = [
        ("alignment", ctypes.c_ulonglong),
        ("next", PIP_ADAPTER_ANYCAST_ADDRESS),
        ("address", SOCKET_ADDRESS)]

    class IP_ADAPTER_MULTICAST_ADDRESS(ctypes.Structure):
        pass
    PIP_ADAPTER_MULTICAST_ADDRESS = ctypes.POINTER(IP_ADAPTER_MULTICAST_ADDRESS)
    IP_ADAPTER_MULTICAST_ADDRESS._fields_ = [
        ("alignment", ctypes.c_ulonglong),
        ("next", PIP_ADAPTER_MULTICAST_ADDRESS),
        ("address", SOCKET_ADDRESS)]

    class IP_ADAPTER_DNS_SERVER_ADDRESS(ctypes.Structure):
        pass
    PIP_ADAPTER_DNS_SERVER_ADDRESS = ctypes.POINTER(IP_ADAPTER_DNS_SERVER_ADDRESS)
    IP_ADAPTER_DNS_SERVER_ADDRESS._fields_ = [
        ("alignment", ctypes.c_ulonglong),
        ("next", PIP_ADAPTER_DNS_SERVER_ADDRESS),
        ("address", SOCKET_ADDRESS)]

    class IP_ADAPTER_PREFIX(ctypes.Structure):
        pass
    PIP_ADAPTER_PREFIX = ctypes.POINTER(IP_ADAPTER_PREFIX)
    IP_ADAPTER_PREFIX._fields_ = [
        ("alignment", ctypes.c_ulonglong),
        ("next", PIP_ADAPTER_PREFIX),
        ("address", SOCKET_ADDRESS),
        ("prefixLength", ctypes.c_ulong)]

    class IP_ADAPTER_WINS_SERVER_ADDRESS(ctypes.Structure):
        pass
    PIP_ADAPTER_WINS_SERVER_ADDRESS = ctypes.POINTER(IP_ADAPTER_WINS_SERVER_ADDRESS)
    IP_ADAPTER_WINS_SERVER_ADDRESS._fields_ = [
        ("alignment", ctypes.c_ulonglong),
        ("next", PIP_ADAPTER_WINS_SERVER_ADDRESS),
        ("address", SOCKET_ADDRESS)]

    class IP_ADAPTER_GATEWAY_ADDRESS(ctypes.Structure):
        pass
    PIP_ADAPTER_GATEWAY_ADDRESS = ctypes.POINTER(IP_ADAPTER_GATEWAY_ADDRESS)
    IP_ADAPTER_GATEWAY_ADDRESS._fields_ = [
        ("alignment", ctypes.c_ulonglong),
        ("next", PIP_ADAPTER_GATEWAY_ADDRESS),
        ("address", SOCKET_ADDRESS)]

    #ifdef.h
    class NET_LUID(ctypes.Structure):
        _fields_ = [
            ("value", ctypes.c_ulonglong)]

    class GUID(ctypes.Structure):
        _fields_ = [
            ("data1", ctypes.wintypes.DWORD),
            ("data2", ctypes.wintypes.WORD),
            ("data3", ctypes.wintypes.WORD),
            ("data4", ctypes.c_byte * 8)]

    MAX_DNS_SUFFIX_STRING_LENGTH = 256
    class IP_ADAPTER_DNS_SUFFIX(ctypes.Structure):
        pass
    PIP_ADAPTER_DNS_SUFFIX = ctypes.POINTER(IP_ADAPTER_DNS_SUFFIX)
    IP_ADAPTER_DNS_SUFFIX._fields_ = [
        ("next", PIP_ADAPTER_DNS_SUFFIX),
        ("string", ctypes.c_wchar * MAX_DNS_SUFFIX_STRING_LENGTH)]

    class IP_ADAPTER_ADDRESSES(ctypes.Structure):
        pass
    PIP_ADAPTER_ADDRESSES = ctypes.POINTER(IP_ADAPTER_ADDRESSES)
    MAX_DHCPV6_DUID_LENGTH = 130 #IPTypes.h
    IP_ADAPTER_ADDRESSES._fields_ = [
        ("header", HEADER_UNION),
        ("next", PIP_ADAPTER_ADDRESSES),
        ("adapterName", ctypes.c_char_p),
        ("firstUnicastAddress", PIP_ADAPTER_UNICAST_ADDRESS),
        ("firstAnycastAddress", PIP_ADAPTER_ANYCAST_ADDRESS),
        ("firstMulticastAddress", PIP_ADAPTER_MULTICAST_ADDRESS),
        ("firstDnsServerAddress", PIP_ADAPTER_DNS_SERVER_ADDRESS),
        ("dnsSuffix", ctypes.c_wchar_p),
        ("description", ctypes.c_wchar_p),
        ("friendlyName", ctypes.c_wchar_p),
        ("physicalAddress", ctypes.c_ubyte * MAX_ADAPTER_ADDRESS_LENGTH),
        ("physicalAddressLength", ctypes.wintypes.DWORD),
        ("flags", ctypes.wintypes.DWORD),
        ("mtu", ctypes.wintypes.DWORD),
        ("ifType", ctypes.wintypes.DWORD),
        ("operStatus", ctypes.c_int),
        ("ipv6IfIndex", ctypes.wintypes.DWORD),
        ("zoneIndices", ctypes.wintypes.DWORD * 16),
        ("firstPrefix", PIP_ADAPTER_PREFIX),
        ("transmitLinkSpeed", ctypes.c_ulonglong),
        ("receiveLinkSpeed", ctypes.c_ulonglong),
        ("firstWinsServerAddress", PIP_ADAPTER_WINS_SERVER_ADDRESS),
        ("firstGatewayAddress", PIP_ADAPTER_GATEWAY_ADDRESS),
        ("ipv4Metric", ctypes.c_ulong),
        ("ipv6Metric", ctypes.c_ulong),
        ("luid", NET_LUID),#ifdef.h
        ("dhcpv4Server", SOCKET_ADDRESS),
        ("compartmentId", ctypes.c_uint32),#ifdef.h
        ("networkGuid", GUID),
        ("connectionType", ctypes.c_int),
        ("tunnelType", ctypes.c_int),
        ("dhcpv6Server", SOCKET_ADDRESS),
        ("dhcpv6ClientDuid", ctypes.c_byte * MAX_DHCPV6_DUID_LENGTH),
        ("dhcpv6ClientDuidLength", ctypes.c_ulong),
        ("dhcpv6Iaid", ctypes.c_ulong)]

    GetAdaptersAddresses = ctypes.windll.iphlpapi.GetAdaptersAddresses
    GetAdaptersAddresses.restype = ctypes.c_ulong
    GetAdaptersAddresses.argtypes = [
        ctypes.c_ulong, ctypes.c_ulong, ctypes.c_void_p,
        PIP_ADAPTER_ADDRESSES, ctypes.POINTER(ctypes.c_ulong)]

    outBufLen = ctypes.c_ulong(15000)
    adapters = ctypes.pointer(IP_ADAPTER_ADDRESSES())
    ctypes.resize(adapters, outBufLen.value)

    from socket import AF_INET
    GAA_FLAG_INCLUDE_PREFIX = ctypes.c_ulong(0x0010)

    GetAdaptersAddresses(ctypes.c_ulong(AF_INET), GAA_FLAG_INCLUDE_PREFIX, None,
                         adapters, ctypes.byref(outBufLen))

    a = adapters[0]
    ifaces = {}
    while a:
        iface = {}

        iface['desc'] = a.description

#        iface['mac'] = ':'.join(["%02X" % part for part in a.address])
#                  
#        adNode = a.ipAddressList
#        iface['ip'] = []
#        while True:
#            ipAddr = adNode.ipAddress
#            if ipAddr:
#                iface['ip'].append( (ipAddr, adNode.ipMask) )
#            if adNode.next:
#                adNode = adNode.next.contents
#            else:
#                break

        ifaces[a.adapterName] = iface

        if a.next:
            a = a.next.contents
        else:
            break


    return ifaces    

def __getInterfaces_win2k():
    import ctypes.wintypes

    MAX_ADAPTER_NAME_LENGTH = 256
    MAX_ADAPTER_DESCRIPTION_LENGTH = 128

    class IP_ADDR_STRING(ctypes.Structure):
        pass
    LP_IP_ADDR_STRING = ctypes.POINTER(IP_ADDR_STRING)
    IP_ADDR_STRING._fields_ = [
        ("next", LP_IP_ADDR_STRING),
        ("ipAddress", ctypes.c_char * 16),
        ("ipMask", ctypes.c_char * 16),
        ("context", ctypes.wintypes.DWORD)]

    class IP_ADAPTER_INFO (ctypes.Structure):
        pass
    LP_IP_ADAPTER_INFO = ctypes.POINTER(IP_ADAPTER_INFO)
    IP_ADAPTER_INFO._fields_ = [
        ("next", LP_IP_ADAPTER_INFO),
        ("comboIndex", ctypes.wintypes.DWORD),
        ("adapterName", ctypes.c_char * (MAX_ADAPTER_NAME_LENGTH + 4)),
        ("description", ctypes.c_char * (MAX_ADAPTER_DESCRIPTION_LENGTH + 4)),
        ("addressLength", ctypes.c_uint),
        ("address", ctypes.c_ubyte * MAX_ADAPTER_ADDRESS_LENGTH),
        ("index", ctypes.wintypes.DWORD),
        ("type", ctypes.c_uint),
        ("dhcpEnabled", ctypes.c_uint),
        ("currentIpAddress", LP_IP_ADDR_STRING),
        ("ipAddressList", IP_ADDR_STRING),
        ("gatewayList", IP_ADDR_STRING),
        ("dhcpServer", IP_ADDR_STRING),
        ("haveWins", ctypes.c_uint),
        ("primaryWinsServer", IP_ADDR_STRING),
        ("secondaryWinsServer", IP_ADDR_STRING),
        ("leaseObtained", ctypes.c_ulong),
        ("leaseExpires", ctypes.c_ulong)]

    GetAdaptersInfo = ctypes.windll.iphlpapi.GetAdaptersInfo
    GetAdaptersInfo.restype = ctypes.wintypes.DWORD
    GetAdaptersInfo.argtypes = [LP_IP_ADAPTER_INFO, ctypes.POINTER(ctypes.c_ulong)]

    adapters = ctypes.pointer(IP_ADAPTER_INFO())
    buflen = ctypes.c_ulong(ctypes.sizeof(IP_ADAPTER_INFO))
    GetAdaptersInfo(adapters, ctypes.byref(buflen))

    ctypes.resize(adapters, buflen.value)
    GetAdaptersInfo(adapters, ctypes.byref(buflen))

    a = adapters.contents
    ifaces = {}
    while a:
        iface = {}

        iface['desc'] = a.description

        iface['mac'] = ':'.join(["%02X" % part for part in a.address])

        adNode = a.ipAddressList
        iface['ip'] = []
        while True:
            ipAddr = adNode.ipAddress
            if ipAddr:
                iface['ip'].append( (ipAddr, adNode.ipMask) )
            if adNode.next:
                adNode = adNode.next.contents
            else:
                break

        ifaces[a.adapterName] = iface

        if a.next:
            a = a.next.contents
        else:
            break


    return ifaces

if __name__ == "__main__":
    ifaces = getInterfaces()
    for k, v in ifaces.iteritems():
        print k
        for k2, v2 in v.iteritems():
            print '\t', k2, v2

不知道这是否是问题的原因,但NET_LUID结构的最后一个字段似乎丢失了:64位宽的“Info”结构。IP适配器地址结构(FirstDnsSuffix)的最后一个字段也丢失了,但这只在W2k8服务器上才重要-我猜您是在Vista或XP中使用此代码。

不知道这是否是问题的原因,但NET LUID结构的最后一个字段似乎丢失了:64位宽的“Info”结构。此外,IP适配器地址结构(FirstDnsSuffix)的最后一个字段丢失,但这只在W2k8服务器上起作用-我猜您正在将此代码用于Vista或XP。

我找不到有关ctypes字节大小的python版本更改的任何信息,但是考虑到IP适配器信息结构和时间大小,我遇到了一个问题

可以在这里找到解决方案

所以也许可以改变路线

("leaseObtained", ctypes.c_ulong) 
("leaseExpires", ctypes.c_ulong)


我找不到关于ctypes字节大小的python版本更改的任何信息,但是考虑到IP适配器信息结构和时间大小,我遇到了一个问题

可以在这里找到解决方案

所以也许可以改变路线

("leaseObtained", ctypes.c_ulong) 
("leaseExpires", ctypes.c_ulong)


您可以在中找到适用于Windows网络的ctypes Python函数
示例

您可以在中找到适用于Windows网络的ctypes Python函数 例如

NET\u LUID是“ULONG64值”和“结构信息”的并集。为简单起见,我将其定义为“ULONG64值”。NET_LUID是“ULONG64值”和“结构信息”的并集。为简单起见,我将其定义为“ULONG64值”。