我想知道如何让 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/