簡體   English   中英

在 Python 中確定計算機是否通過 WiFi 網絡或以太網電纜連接到 Internet

[英]Determine if a computer is connected to internet via WiFi network or ethernet cable in Python

我想知道如何讓 Python 腳本確定計算機如何連接到網絡。 原因是如果連接速度太慢,腳本會出現錯誤,所以如果用戶通過 WiFi 連接,我想顯示警告。

正在運行的實際 Python 可執行文件位於我公司的 LAN 上,因此這就是連接速度很重要的原因。 此外,由於此可執行文件在沒有連接的情況下無法運行,因此我不關心檢查用戶是否在線。

我對 Python 如何與這樣的事情交互(或者即使它可能)一無所知,所以如果有什么我可以澄清的,請告訴我。 提前致謝

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

在 Windows 上,此信息通過 WMI 的網絡適​​配器類提供

在 .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這個 IANA 列表中的一個數字。 (如果您想解析 SNMP MIB,您可以 通過這種方式下載它。)請注意,Windows 可能會將一些不太常見/過時的適配器類型與以太網混為一談,但您可能並不關心這一點。


對於舊版本的 Windows——我不確定 Windows 7 是否算作“舊版”——你需要Win32_NetworkAdapter和朋友,而不是上面鏈接的MSFT_NetworkAdapter / NetworkAdapter ,所以代碼會有所不同。

特別是,獲取提供默認 Internet 連接的適配器更難,但更靈活,而獲取其類型更容易,但信息較少。 IIRC,至少在XP中,即使Windows有“網絡連接”的一些想法,你無法通過訪問WMI的,但你可以訪問所有的網絡連接,或搜索/迭代對於您所關心的一個。 如果您有 VPN,或者坐在 DMZ 上,或者同時有多個 NIC 卡處於活動狀態等,這實際上會更好。

因此,您要做的是搜索或迭代Win32_IP4RouteTable以查找哪個連接路由處理您實際要連接的 IP 地址,或者使用Win32_NetworkAdapaterConfiguration查找哪個 NIC 處理您要連接的地址。 無論哪種方式,您都會獲得一個InterfaceIndex ,並且您可以使用該InterfaceIndex查找Win32_NetworkAdapter 然后它的AdapterType是一個不錯的字符串,您只需檢查!= "Wireless" (我相信我從TechNet 腳本中心的 VBscript 示例中弄清楚了所有這些,然后自己將其移植到 IronPython,但那是很久以前的事了,所以我可能記錯了。無論如何,文檔似乎比他們做的更完整那時,所以應該沒有必要。)


如果沒有 .NET(例如,使用標准 CPython),您必須使用 Web 服務接口,或者與本機 Win32 COM 接口通信。

理論上,您可以通過ctypes直接與 COM 接口通信,但這是一個可怕的想法; 你幾乎肯定想要pywin32

而且,更好的是,我建議在 PyPI 上四處尋找包裝器,比如這個,而不是自己構建它。 然后,代碼應該幾乎和 .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”。 使用=可能會在那里工作,誰知道; 通讀教程以找出答案。

另一方面,按目標地址搜索應該是這樣的:

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

使用 WMI,您無需本地計算機 IP 即可確定連接。

使用NetConnectionID而不是AdapterType進行比較似乎有效。

適用於 Windows 10。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM