确定计算机是否通过WiFi网络或Python中的以太网电缆连接到Internet

时间:2013-12-24 19:59:30

标签: python windows

我想知道如何让Python脚本确定计算机如何连接到网络。原因是因为如果连接速度太慢,脚本就会出现问题,所以如果用户通过WiFi连接,我想显示警告。

正在运行的实际Python可执行文件位于我公司的LAN上,因此连接速度很重要。此外,由于此可执行文件无法在没有连接的情况下运行,因此我不关心检查用户是否在线。

我对Python如何与这样的事情(或者即使它可能)进行交互一无所知,所以如果有任何我可以澄清的话,请告诉我。提前致谢

我在Windows 7 64位上使用32位32位Python(不同位因为pyEnchant)

1 个答案:

答案 0 :(得分:3)

在Windows上,此信息可通过WMI的Network Adapter Classes

获取

在.NET中(例如,使用IronPython),这很容易使用:

ni = Windows.Networking.Connectivity.NetworkInformation
profile = ni.GetInternetConnectionProfile()
if profile:
    interface = profile.NetworkAdapter.IanaInterfaceType
    if interface == 71:
        do WiFi stuff
    elif interface == 6:
        do Ethernet stuff
    else:
        do wtf stuff

IanaInterfaceType是来自this IANA list的数字。 (我想要解析SNMP MIB,你可以download it that way。)请注意,Windows可能会将一些不太常见/过时的适配器类型与以太网混为一谈,但您可能并不关心它。


对于旧版本的Windows - 我不确定Windows 7是否计为“较旧” - 您需要Win32_NetworkAdapter和朋友,而不是MSFT_NetworkAdapter / NetworkAdapter ,所以代码会有所不同。

特别是,获取提供默认互联网连接的适配器更难,但更灵活,而获取其类型更容易,但信息量较少。 IIRC,至少在XP中,即使Windows有一些“ 互联网连接”的概念,你也无法通过WMI访问它 - 但你可以访问所有互联网连接,或搜索/迭代你关心的那个。如果您有VPN,或者坐在DMZ上,或者同时激活多个NIC卡等,这实际上更好。

因此,您要做的是搜索或迭代Win32_IP4RouteTable以查找哪条连接路由处理您实际要连接的IP地址,或使用Win32_NetworkAdapaterConfiguration查找哪个NIC处理您想要的地址来自。无论哪种方式,您都会获得InterfaceIndex,然后您可以使用InterfaceIndex查找Win32_NetworkAdapter。然后它的AdapterType是一个很好的字符串,你可以检查!= "Wireless"。 (我相信我从TechNet Script Center的一个VBscript示例中找到了所有这些,然后自己将它移植到IronPython,但是很久以前,所以我可能记得错了。无论如何,文档似乎比他们当时做了,所以这不应该是必要的。)


没有.NET(例如,使用标准的CPython),您必须使用Web服务接口,或者与本机Win32 COM接口通信。

理论上,您可以通过ctypes直接与COM界面交谈,但这是一个可怕的想法;你几乎肯定想要pywin32

而且,更好的是,我建议在PyPI上查找包装器,例如this one,而不是自己构建它。然后,代码应该与.NET一样简单。


这是使用上面链接的WMI库和上面描述的XP兼容的源地址方法的一些伪代码:

import wmi
MY_IP = '10.1.2.3'
w = wmi.WMI()
for nac in w.Win32_NetworkAdapterConfiguration():
    if MY_IP in nac.IPAddress:
        idx = nac.InterfaceIndex
        break
else:
    oops, do something, no NIC has that address
na = w.Win32_NetworkAdapter(InterfaceIndex=idx)
if not na:
    oops, unlikely race condition, NIC disabled right before we checked it
if na[0].AdapterType == 'Wireless':
    do WiFi stuff
elif na[0].AdapterType.startswith('Ethernet'):
    do Ethernet stuff
else:
    who's using LocalTalk in 2013?

应该可以搜索NetworkAddressConfiguration,但我不知道如何在wmi库中搜索“IPAddress contains MY_IP”。使用=可能会在那里工作,谁知道;仔细阅读tutorial以找出答案。

另一方面,按目标地址搜索应该是这样的:

TARGET_IP = '10.10.10.10'
w = wmi.WMI()
rt = w.Win32_IP4RouteTable(Destination=TARGET_IP)
if not rt:
    oops, no route to host
idx = rt[0].InterfaceIndex
# same as above