使用“WlanScan”刷新 WiFi 网络列表

您所在的位置:网站首页 win7刷新wifi 使用“WlanScan”刷新 WiFi 网络列表

使用“WlanScan”刷新 WiFi 网络列表

2024-07-09 11:58| 来源: 网络整理| 查看: 265

我认为您不刷新的主要问题是您永远不会关闭打开的句柄。这可能会导致问题,因为不应该有多个打开的句柄 afaik。

您用于WlanOpenHandle获取接口的句柄,但在完成并获得所需信息后,您应该调用WlanCloseHandle以关闭该句柄和关联的连接。

Declare PtrSafe Function WlanCloseHandle Lib "Wlanapi.dll" ( _

  ByVal hClientHandle As LongPtr, _

  Optional ByVal pReserved As LongPtr) As Long

然后在你的函数结束时:

    WlanCloseHandle lngHandle 'Close handle

    GetWiFi = wifiOut   'Success! (function is populated with cached network list)

End Function

任何错误处理程序,如果要添加一个,应该测试句柄是否不为 0,如果不是,则关闭它。

我还更改了各种小东西,例如使用LongPtrfor 指针使您的代码与 64 位兼容(注意:它不兼容 VBA6,需要大量条件编译),重新编写声明以不使用可选参数,以及一些其他小事。

我在一个设备上用 10 次迭代测试了以下代码,得到了 10 个不同的结果:

代码:

Public Function GetWiFi() As wifis()

'returns an array of custom type WiFis (1st interface only)

    Dim udtList As WLAN_INTERFACE_INFO_LIST, udtAvailList As WLAN_AVAILABLE_NETWORK_LIST, udtNetwork As WLAN_AVAILABLE_NETWORK

    Dim lngReturn As Long, pHandle As LongPtr, lngVersion As Long, pList As LongPtr, pAvailable As LongPtr

    Dim pStart As LongPtr, intCount As Integer, ssid As String, signal As Single, wifiOut() As wifis

    Dim n As Long

    n = 0

    lngReturn = WlanOpenHandle(2&, 0&, lngVersion, pHandle) 'get handle

    If lngReturn 0 Then

        Debug.Print "Couldn't get wlan handle (Code " & lngReturn & ")"

        Exit Function

    End If

    lngReturn = WlanEnumInterfaces(ByVal pHandle, 0&, pList) 'enumerate

    CopyMemory udtList, ByVal pList, Len(udtList)

    lngReturn = WlanScan(pHandle, udtList.InterfaceInfo.ifGuid)

    lngReturn = WlanGetAvailableNetworkList(pHandle, udtList.InterfaceInfo.ifGuid, 2&, 0&, pAvailable) 'get network list

    CopyMemory udtAvailList, ByVal pAvailable, LenB(udtAvailList)

    intCount = 0

    pStart = pAvailable + 8

    Do

        CopyMemory udtNetwork, ByVal pStart, Len(udtNetwork) ' Populate avail. network structure

        ssid = Replace(StrConv(udtNetwork.dot11Ssid.ucSSID, vbUnicode), Chr(0), "")

        If Len(ssid) < 4 Then ssid = "(Unnamed)"

        signal = CSng(udtNetwork.wlanSignalQuality) / 100

        '[Signal] = 0 to 100 which represents the signal strength (100 Signal)=(-100dBm RSSI), (100 Signal)=(-50dBm RSSI)

        If udtNetwork.dwflags = 0 Then

            n = n + 1

            ReDim Preserve wifiOut(n)

            wifiOut(n).ssid = ssid

            wifiOut(n).signal = signal

        Else

            'skipping networks with [dwflags] > 0

            'I *think* that's what I'm supposed to do

            'Returns 3 for currently connected network, 2 for networks that have profiles

        End If

        intCount = intCount + 1

        pStart = pStart + Len(udtNetwork)

    Loop Until intCount = udtAvailList.dwNumberOfItems

    WlanFreeMemory pAvailable     'clean up memory

    WlanFreeMemory pList

    WlanCloseHandle pHandle 'Close handle

    GetWiFi = wifiOut   'Success! (function is populated with cached network list)

End Function

类型和常量:

Private Const DOT11_SSID_MAX_LENGTH As Long = 32

Private Const WLAN_MAX_PHY_TYPE_NUMBER As Long = 8

Private Const WLAN_AVAILABLE_NETWORK_CONNECTED As Long = 1

Private Const WLAN_AVAILABLE_NETWORK_HAS_PROFILE As Long = 2

Public Type GUID

    Data(15) As Byte

End Type

Private Type WLAN_INTERFACE_INFO

    ifGuid As GUID: InterfaceDescription(255) As Byte: IsState As Long

End Type

Private Type DOT11_SSID

    uSSIDLength As Long:            ucSSID(DOT11_SSID_MAX_LENGTH - 1) As Byte

End Type

Private Type WLAN_AVAILABLE_NETWORK

    strProfileName(511) As Byte:    dot11Ssid As DOT11_SSID

    dot11BssType As Long:           uNumberOfBssids As Long

    bNetworkConnectable As Long:    wlanNotConnectableReason As Long

    uNumberOfPhyTypes As Long:      dot11PhyTypes(WLAN_MAX_PHY_TYPE_NUMBER - 1) As Long

    bMorePhyTypes As Long:          wlanSignalQuality As Long

    bSEcurityEnabled As Long:       dot11DefaultAuthAlgorithm As Long

    dot11DefaultCipherAlgorithm As Long: dwflags As Long: dwReserved As Long

End Type

Private Type WLAN_INTERFACE_INFO_LIST

    dwNumberOfItems As Long: dwIndex As Long: InterfaceInfo As WLAN_INTERFACE_INFO

End Type

Private Type WLAN_AVAILABLE_NETWORK_LIST

    dwNumberOfItems As Long:  dwIndex As Long: Network As WLAN_AVAILABLE_NETWORK

End Type

Public Type WiFis

  ssid As String: signal As Single

End Type

函数声明:

Declare PtrSafe Function WlanOpenHandle Lib "Wlanapi.dll" (ByVal dwClientVersion As Long, _

                ByVal pdwReserved As LongPtr, ByRef pdwNegotiaitedVersion As Long, _

                ByRef phClientHandle As LongPtr) As Long

Declare PtrSafe Function WlanEnumInterfaces Lib "Wlanapi.dll" (ByVal hClientHandle As LongPtr, _

                ByVal pReserved As LongPtr, ByRef ppInterfaceList As LongPtr) As Long

Declare PtrSafe Function WlanGetAvailableNetworkList Lib "Wlanapi.dll" ( _

                ByVal hClientHandle As LongPtr, ByRef pInterfaceGuid As GUID, ByVal dwflags As Long, _

                ByVal pReserved As LongPtr, ByRef ppAvailableNetworkList As LongPtr) As Long

Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, _

                Source As Any, ByVal Length As Long)

Declare PtrSafe Function WlanScan Lib "Wlanapi.dll" _

        (ByVal hClientHandle As LongPtr, ByRef pInterfaceGuid As GUID, _

        Optional ByVal pDot11Ssid As LongPtr, Optional ByVal pIeData As LongPtr, _

        Optional ByVal pReserved As LongPtr) As Long

Declare PtrSafe Function WlanCloseHandle Lib "Wlanapi.dll" ( _

  ByVal hClientHandle As LongPtr, _

  Optional ByVal pReserved As LongPtr) As Long

Declare PtrSafe Sub WlanFreeMemory Lib "Wlanapi.dll" (ByVal pMemory As LongPtr)

测试调用以打印列表:

Public Sub PrintWifis()

    Dim aWifis() As wifis

    aWifis = GetWiFi

    Dim l As Long

    For l = LBound(aWifis) To UBound(aWifis)

        Debug.Print aWifis(l).ssid; aWifis(l).signal

    Next

End Sub



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3