
1. Native Wifi API基础入门Windows平台下管理WiFi网络最直接的方式就是调用系统自带的Native Wifi API。这套接口藏在wlanapi.h头文件里通过它我们可以实现扫描热点、连接网络、监控状态等核心功能。先来看个最简单的例子——如何初始化API环境#include windows.h #include wlanapi.h #pragma comment(lib, wlanapi.lib) HANDLE hClient NULL; DWORD dwVersion 0; // 初始化WLAN客户端 DWORD dwResult WlanOpenHandle(2, NULL, dwVersion, hClient); if (dwResult ! ERROR_SUCCESS) { std::cerr 初始化失败错误码: dwResult std::endl; return -1; }这里有几个关键点需要注意WlanOpenHandle的第二个参数保留为NULL即可第一个参数2表示请求的API版本实际版本会通过第三个参数返回记得检查返回值非ERROR_SUCCESS表示操作失败初始化完成后这个hClient句柄就像一把钥匙后续所有操作都需要它。用完记得用WlanCloseHandle关闭否则会导致资源泄漏。2. 实时监控WiFi状态变化2.1 回调函数注册机制要实现网络状态监控核心是WlanRegisterNotification这个函数。它允许我们注册一个回调函数当WiFi状态变化时系统会自动通知我们。先看代码框架// 符合Windows回调规范的正确定义 DWORD WINAPI WifiCallback( PWLAN_NOTIFICATION_DATA pData, PVOID pContext) { // 处理通知逻辑 return ERROR_SUCCESS; } // 注册通知回调 dwResult WlanRegisterNotification( hClient, WLAN_NOTIFICATION_SOURCE_ACM, // 只关注连接管理事件 TRUE, (WLAN_NOTIFICATION_CALLBACK)WifiCallback, NULL, NULL, NULL );这里有个新手常踩的坑回调函数必须使用WINAPI调用约定返回DWORD类型。如果定义成普通函数系统将无法正确调用。2.2 事件类型过滤WiFi事件主要分为几大类连接完成 (wlan_notification_acm_connection_complete)断开连接 (wlan_notification_acm_disconnected)扫描完成 (wlan_notification_acm_scan_complete)建议在回调函数里先判断事件来源避免处理无关通知if (pData-NotificationSource ! WLAN_NOTIFICATION_SOURCE_ACM) { return ERROR_SUCCESS; } switch (pData-NotificationCode) { case wlan_notification_acm_connection_complete: // 处理新连接 break; case wlan_notification_acm_disconnected: // 处理断开事件 break; }3. 智能重连机制实现3.1 状态机设计一个健壮的重连系统需要维护连接状态。推荐用枚举定义状态enum WifiState { DISCONNECTED, CONNECTING, CONNECTED, RECONNECTING }; // 全局状态变量 std::atomicWifiState g_currentState DISCONNECTED;在回调函数中更新状态case wlan_notification_acm_connection_complete: g_currentState CONNECTED; break; case wlan_notification_acm_disconnected: if (g_currentState CONNECTED) { g_currentState RECONNECTING; StartReconnect(); } break;3.2 重连策略优化直接无脑重连可能适得其反。建议实现以下策略首次断开立即重连后续失败采用指数退避1s, 2s, 4s...达到最大重试次数后暂停示例代码void StartReconnect() { static int retryCount 0; const int maxRetry 5; if (retryCount maxRetry) { std::cout 超过最大重试次数暂停重连 std::endl; return; } int delay (1 retryCount) * 1000; // 指数退避 std::this_thread::sleep_for(std::chrono::milliseconds(delay)); if (ConnectToSavedNetwork() ERROR_SUCCESS) { retryCount 0; } else { retryCount; StartReconnect(); // 递归调用 } }4. 完整工具开发实战4.1 项目结构设计推荐采用模块化设计WiFiManager/ ├── include/ │ ├── WifiScanner.h // 扫描功能 │ ├── WifiConnector.h // 连接功能 │ └── WifiMonitor.h // 状态监控 └── src/ ├── main.cpp // 主循环 └── SystemTray.cpp // 系统托盘界面4.2 关键功能实现扫描热点示例std::vectorWifiNetwork ScanNetworks() { PWLAN_INTERFACE_INFO_LIST pIfList NULL; PWLAN_AVAILABLE_NETWORK_LIST pNetList NULL; std::vectorWifiNetwork results; // 获取无线接口列表 if (WlanEnumInterfaces(hClient, NULL, pIfList) ! ERROR_SUCCESS) { return results; } // 遍历每个接口扫描网络 for (DWORD i 0; i pIfList-dwNumberOfItems; i) { GUID interfaceGuid pIfList-InterfaceInfo[i].InterfaceGuid; WlanScan(hClient, interfaceGuid, NULL, NULL, NULL); // 获取可用网络列表 if (WlanGetAvailableNetworkList( hClient, interfaceGuid, 0, NULL, pNetList) ERROR_SUCCESS) { for (DWORD j 0; j pNetList-dwNumberOfItems; j) { WifiNetwork network; // 解析网络信息... results.push_back(network); } } } // 释放资源 if (pIfList) WlanFreeMemory(pIfList); if (pNetList) WlanFreeMemory(pNetList); return results; }连接网络示例DWORD ConnectToNetwork(const std::wstring profileName) { WLAN_CONNECTION_PARAMETERS params {0}; params.wlanConnectionMode wlan_connection_mode_profile; params.strProfile profileName.c_str(); params.dot11BssType dot11_BSS_type_infrastructure; params.dwFlags 0; return WlanConnect(hClient, interfaceGuid, params, NULL); }4.3 系统托盘集成使用Windows API创建托盘图标NOTIFYICONDATA nid {0}; nid.cbSize sizeof(NOTIFYICONDATA); nid.hWnd hWnd; nid.uID 1; nid.uFlags NIF_ICON | NIF_MESSAGE | NIF_TIP; nid.uCallbackMessage WM_APP 1; nid.hIcon LoadIcon(hInst, MAKEINTRESOURCE(IDI_APPICON)); wcscpy_s(nid.szTip, LWiFi监控工具); Shell_NotifyIcon(NIM_ADD, nid);5. 常见问题排查指南回调不触发怎么办检查函数签名是否正确确认注册时使用了WLAN_NOTIFICATION_SOURCE_ACM确保程序有消息循环GUI或GetMessage连接失败排查步骤检查WlanConnect返回值查看系统事件日志事件查看器-Windows日志-系统尝试手动连接相同热点确认密码是否正确内存泄漏预防所有通过Wlan系列函数获取的内存指针必须用WlanFreeMemory释放PWLAN_INTERFACE_INFO_LIST pList NULL; WlanEnumInterfaces(hClient, NULL, pList); // 使用pList... WlanFreeMemory(pList); // 必须调用6. 性能优化技巧减少扫描频率后台扫描间隔建议不少于30秒使用缓存热点列表可缓存5-10秒异步操作耗时操作放到单独线程精准通知只订阅必要的事件类型// 只订阅连接相关事件 DWORD notifSources WLAN_NOTIFICATION_SOURCE_ACM; WlanRegisterNotification(hClient, notifSources, ...);在开发过程中我遇到最棘手的问题是回调函数偶尔会重复触发。后来发现是因为没有正确处理WLAN_NOTIFICATION_SOURCE_ALL导致收到大量无关通知。改用精确的事件源过滤后问题迎刃而解。