You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

切换接入点时Native WiFi报错,VB.Net网络监控APP SSID检测问题

解决VB.Net中Native Wifi SSID变更检测的报错与事件监听问题

看起来你在做一个挺实用的WiFi监控工具,可惜卡在了SSID切换检测的问题上——那个WlanReasonCode的封送错误和低效的轮询方式确实挺头疼的,我来给你一步步解决:

一、先搞定WlanReasonCode的封送错误

这个错误大概率是你用的NativeWifi库中,对WlanReasonCode这个枚举/结构体的非托管封送定义不匹配导致的。如果是你自己封装的NativeWifi API,检查一下枚举的定义,确保它是基于UInteger的,并且和Windows官方的WLAN_REASON_CODE枚举完全对应,比如:

<Flags>
Public Enum WlanReasonCode As UInteger
    Success = 0
    Unspecified = 1
    AuthFailure = 2
    ' 这里补全所有需要的枚举值,参考微软官方文档的WLAN_REASON_CODE
End Enum

如果是用第三方封装的库,要么换个更靠谱的版本,要么先试试用.NET自带的NetworkInformation类做降级方案,暂时避开这个封送问题。

二、扔掉轮询,用事件监听精准捕获SSID变化

你现在用的轮询方式不仅效率低,还容易错过SSID切换的瞬间,而且很容易触发资源访问冲突。Windows本身提供了WiFi状态变化的通知事件,我们可以直接在VB.Net中监听WlanClient的通知事件,这样能精准捕获连接/断开的瞬间:

步骤1:初始化并注册事件

在你的主窗体加载时,初始化WlanClient并注册事件:

Private wlanClient As WlanClient

Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    wlanClient = New WlanClient()
    ' 注册WiFi状态变化的通知事件
    AddHandler wlanClient.WlanNotificationReceived, AddressOf OnWlanNotification
End Sub

步骤2:编写事件处理器

这个函数会在WiFi状态变化时自动触发,我们只需要关注连接完成和断开的事件,然后更新当前SSID:

Private Sub OnWlanNotification(sender As Object, e As WlanNotificationEventArgs)
    ' 只处理连接/断开的通知
    If e.NotificationCode = Wlan.WlanNotificationCodeACM.ConnectionComplete OrElse
       e.NotificationCode = Wlan.WlanNotificationCodeACM.Disconnect Then

        ' 注意:事件是在后台线程触发的,必须切换到UI线程更新控件
        Me.Invoke(Sub()
                      UpdateCurrentSSID()
                  End Sub)
    End If
End Sub

Private Sub UpdateCurrentSSID()
    Dim currentSSID = "Not Connected"
    ' 找到当前处于连接状态的WiFi接口
    Dim connectedInterface = wlanClient.Interfaces.FirstOrDefault(Function(i) i.InterfaceState = Wlan.WlanInterfaceState.Connected)
    
    If connectedInterface IsNot Nothing Then
        Dim ssidData = connectedInterface.CurrentConnection.wlanAssociationAttributes.dot11Ssid
        currentSSID = Encoding.ASCII.GetString(ssidData.SSID, 0, CInt(ssidData.SSIDLength))
    End If

    MainForm.NetLabelAP.Text = $"Current AP: {currentSSID}"
End Sub

步骤3:清理事件(避免内存泄漏)

在窗体关闭时记得移除事件处理器,不然可能会有内存泄漏的问题:

Private Sub MainForm_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
    If wlanClient IsNot Nothing Then
        RemoveHandler wlanClient.WlanNotificationReceived, AddressOf OnWlanNotification
        wlanClient = Nothing
    End If
End Sub

三、如果暂时不想用事件,优化原有的轮询代码

要是你暂时不想改架构,也可以优化你原来的WhatAP()函数,修复逻辑错误和异常处理:

Public Function WhatAP() As Boolean
    If Not wifiON() Then
        WhatAPResult = "WiFi is Off"
        Return False
    End If

    Try
        Dim wlanx = New WlanClient()
        ' 直接找连接状态的接口,不用遍历所有接口再嵌套循环
        Dim connectedInterface = wlanx.Interfaces.FirstOrDefault(Function(i) i.InterfaceState = Wlan.WlanInterfaceState.Connected)
        
        If connectedInterface IsNot Nothing Then
            Dim ssid = connectedInterface.CurrentConnection.wlanAssociationAttributes.dot11Ssid
            WhatAPResult = Encoding.ASCII.GetString(ssid.SSID, 0, CInt(ssid.SSIDLength))
            Return True
        Else
            WhatAPResult = "Not Connected"
            Return False
        End If
    Catch ex As ArgumentException
        ' 碰到封送错误时,用NetworkInformation做降级处理
        Dim wifiNic = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(Function(n) n.Name = "WiFi" And n.OperationalStatus = OperationalStatus.Up)
        WhatAPResult = If(wifiNic IsNot Nothing, $"WiFi Connected (SSID unavailable)", "WiFi Error")
        Return False
    End Try
End Function

几个关键提醒

  • 跨线程更新UI:事件处理器是在后台线程跑的,一定要用Me.Invoke切换到UI线程更新控件,不然会直接报错。
  • 权限问题:有些WiFi状态信息需要管理员权限才能获取,如果你的程序运行时还是有问题,试试右键以管理员身份启动。
  • NativeWifi库的选择:如果用第三方库,优先选维护活跃的版本,避免踩封送错误的坑。

内容的提问来源于stack exchange,提问作者Josh Watson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:38:18