切换接入点时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
相关产品推荐
相关产品推荐

