python - 在 Python 中确定计算机是否通过 WiFi 网络或以太网电缆连接到互联网

标签 python windows

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

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

我对 Python 如何与此类事物交互(或者即使可能)一无所知,所以如果有任何我可以澄清的地方,请告诉我。提前致谢

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

最佳答案

在 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和 friend ,不是上面链接的 MSFT_NetworkAdapter/NetworkAdapter,所以代码会有所不同。

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

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


如果没有 .NET(例如,使用标准 CPython),您必须使用 Web 服务接口(interface),或者与 native Win32 COM 接口(interface)对话。

理论上,您可以通过 ctypes 直接与 COM 接口(interface)对话,但这是一个糟糕的想法;你几乎肯定想要 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

关于python - 在 Python 中确定计算机是否通过 WiFi 网络或以太网电缆连接到互联网,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20766191/

相关文章:

windows - 有没有办法 Hook 或拦截 CoGetClassObject 和/或 CoCreateInstance 调用?

c++ - Linux 中的 SEH 等效项或如何处理操作系统信号(如 SIGSERV)并继续

python - 在 ubuntu 中运行 buildozer 时找不到 Git (git)

python - 在 azure 函数中找不到本地模块

python - 在 Python 中更新嵌套字典中的值

windows - Anaconda Spyder 4.1.5 更新

python - pylint 给出了达到最大递归深度的许多错误

python - TF-IDF 如何仅获取单词列表

c++ - SetWindowsHookEx() 监控所有线程 : Must the hook procedure be located in a DLL?

python - 将 Python 脚本移动到另一台计算机