Windows 中的 Wifi 通知
Wifi notifications in Windows
我想知道 windows C++ 应用程序如何在 windows 系统更改其 wifi 网络时收到通知。我对以下案例感兴趣:
- 当用户打开 wifi 并连接到新网络时
- 当用户关闭 wifi 并断开与网络的连接时
- 当用户从网络A切换到网络B时
注:切换on/off wifi 不感兴趣。设备需要连接到网络。网络可能有也可能没有互联网连接。
我正在尝试使用 wlanapi.h and have checked out a few examples 实现此目的,但未能实现。
让我知道是否有人能够使用 wlanapi.h 实现此目的。还是有另一种方法?请举例说明。
如有任何帮助,我们将不胜感激。
编辑:添加代码
#include <windows.h>
#include <Wlanapi.h>
#include <iostream>
// Link wlanapi.lib
#pragma comment(lib, "wlanapi.lib")
void DetectWifiNetworkChanges ();
void EventLoop ();
// Callback func to receive network notifications
void WlanNotificationCallback (PWLAN_NOTIFICATION_DATA pData, PVOID pContext);
int main ()
{
DetectWifiNetworkChanges ();
printf ("\n");
getchar ();
return 0;
}
void DetectWifiNetworkChanges ()
{
printf ("DetectWifiNetworkChanges\n");
HANDLE client;
DWORD client_version = 2;
DWORD current_version = 0;
DWORD result;
result = WlanOpenHandle (client_version, NULL, ¤t_version, &client);
if (result != ERROR_SUCCESS) {
printf ("WlanOpenHandle failed !!\n");
return;
}
result = WlanRegisterNotification (client, WLAN_NOTIFICATION_SOURCE_ALL, FALSE, WlanNotificationCallback, NULL, NULL, NULL);
if (result != ERROR_SUCCESS) {
printf ("WlanRegisterNotification failed !!\n");
return;
}
printf ("WlanRegistration successful\n");
// An infinite loop (Ctrl + C to quit the app for now)
EventLoop ();
result = WlanCloseHandle (client, NULL);
if (result != ERROR_SUCCESS) {
printf ("WlanCloseHandle !!\n");
return;
}
}
输出
DetectWifiNetworkChanges
WlanRegistration successful
EventLoop
我尝试连接和断开我的网络,但没有调用回调。
但有时,在我没有断开网络连接的情况下,回调会被调用很多次。
解决方法很简单。
我只需要在注册和捕获回调中的状态时更改通知类型(之前回调为空)。
当registering时,通知源应该是WLAN_NOTIFICATION_SOURCE_ACM。
我捕获了回调中的所有 states。
这是修改后的工作代码
#include <windows.h>
#include <Wlanapi.h>
#include <iostream>
// Link wlanapi.lib
#pragma comment(lib, "wlanapi.lib")
void DetectWifiNetworkChanges ();
void HandleACMNotifications (PWLAN_NOTIFICATION_DATA pNotification);
// Callback func to receive wifi notifications
void WlanNotificationCallback (PWLAN_NOTIFICATION_DATA pData, PVOID pContext);
int
main ()
{
DetectWifiNetworkChanges ();
printf ("\n");
getchar ();
return 0;
}
// Entry point.
// Will be called from int main
void
DetectWifiNetworkChanges ()
{
printf ("DetectWifiNetworkChanges\n");
HANDLE client;
DWORD client_version = 2;
DWORD current_version = 0;
DWORD result;
result = WlanOpenHandle (client_version, NULL, ¤t_version, &client);
if (result != ERROR_SUCCESS) {
printf ("WlanOpenHandle failed !!\n");
return;
}
result = WlanRegisterNotification (client, WLAN_NOTIFICATION_SOURCE_ACM, FALSE, WlanNotificationCallback, NULL, NULL, NULL);
if (result != ERROR_SUCCESS) {
printf ("WlanRegisterNotification failed !!\n");
return;
}
printf ("WlanRegistration successful\n");
// Wait for input from user
// The program pauses here. Toggle the wifi, change wifi network etc.
// to see the wifi notifications
getchar ();
result = WlanCloseHandle (client, NULL);
if (result != ERROR_SUCCESS) {
printf ("WlanCloseHandle !!\n");
return;
}
}
void
WlanNotificationCallback (PWLAN_NOTIFICATION_DATA pNotification, PVOID pContext)
{
printf ("WlanNotificationCallback\n");
if (pNotification->NotificationSource == WLAN_NOTIFICATION_SOURCE_ACM)
HandleACMNotifications (pNotification);
}
void
HandleACMNotifications (PWLAN_NOTIFICATION_DATA pNotification)
{
printf ("HandleACMNotifications\n");
switch (pNotification->NotificationCode) {
case wlan_notification_acm_start:
printf ("wlan_notification_acm_start\n");
break;
case wlan_notification_acm_autoconf_enabled:
printf ("wlan_notification_acm_autoconf_enabled\n");
break;
case wlan_notification_acm_autoconf_disabled:
printf ("wlan_notification_acm_autoconf_disabled\n");
break;
case wlan_notification_acm_background_scan_enabled:
printf ("wlan_notification_acm_background_scan_enabled\n");
break;
case wlan_notification_acm_background_scan_disabled:
printf ("wlan_notification_acm_background_scan_disabled\n");
break;
case wlan_notification_acm_bss_type_change:
printf ("wlan_notification_acm_bss_type_change\n");
break;
case wlan_notification_acm_power_setting_change:
printf ("wlan_notification_acm_power_setting_change\n");
break;
case wlan_notification_acm_scan_complete:
printf ("wlan_notification_acm_scan_complete\n");
break;
case wlan_notification_acm_scan_fail:
printf ("wlan_notification_acm_scan_fail\n");
break;
case wlan_notification_acm_connection_start:
printf ("wlan_notification_acm_connection_start\n");
break;
case wlan_notification_acm_connection_complete:
printf ("wlan_notification_acm_connection_complete\n");
break;
case wlan_notification_acm_connection_attempt_fail:
printf ("wlan_notification_acm_connection_attempt_fail\n");
break;
case wlan_notification_acm_filter_list_change:
printf ("wlan_notification_acm_filter_list_change\n");
break;
case wlan_notification_acm_interface_arrival:
printf ("wlan_notification_acm_interface_arrival\n");
break;
case wlan_notification_acm_interface_removal:
printf ("wlan_notification_acm_interface_removal\n");
break;
case wlan_notification_acm_profile_change:
printf ("wlan_notification_acm_profile_change\n");
break;
case wlan_notification_acm_profile_name_change:
printf ("wlan_notification_acm_profile_name_change\n");
break;
case wlan_notification_acm_profiles_exhausted:
printf ("wlan_notification_acm_profiles_exhausted\n");
break;
case wlan_notification_acm_network_not_available:
printf ("wlan_notification_acm_network_not_available\n");
break;
case wlan_notification_acm_network_available:
printf ("wlan_notification_acm_network_available\n");
break;
case wlan_notification_acm_disconnecting:
printf ("wlan_notification_acm_disconnecting\n");
break;
case wlan_notification_acm_disconnected:
printf ("wlan_notification_acm_disconnected\n");
break;
case wlan_notification_acm_adhoc_network_state_change:
printf ("wlan_notification_acm_adhoc_network_state_change\n");
break;
case wlan_notification_acm_profile_unblocked:
printf ("wlan_notification_acm_profile_unblocked\n");
break;
case wlan_notification_acm_screen_power_change:
printf ("wlan_notification_acm_screen_power_change\n");
break;
case wlan_notification_acm_profile_blocked:
printf ("wlan_notification_acm_profile_blocked\n");
break;
case wlan_notification_acm_scan_list_refresh:
printf ("wlan_notification_acm_scan_list_refresh\n");
break;
case wlan_notification_acm_operational_state_change:
printf ("wlan_notification_acm_operational_state_change\n");
break;
case wlan_notification_acm_end:
printf ("wlan_notification_acm_end\n");
break;
}
}
观察:
当我点击 wifi 图标查看可用网络列表时,调用回调并显示以下通知
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_scan_complete
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_scan_list_refresh
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_network_available
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_profiles_exhausted
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_network_available
注意:WlanNotificationCallback、HandleACMNotifications是我的printfs,如代码所示。根据流程将这两个与通知代码一起粘贴在输出中。
由于系统会在以下情况下扫描并显示可用网络列表,因此将重复这些通知
- 当点击 wifi 图标选择并连接网络时
- 当与网络断开连接时和可用网络列表
再次可见。
断开网络时收到的通知:
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_scan_complete
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_scan_list_refresh
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_profile_change
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_disconnecting
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_disconnected
连接到网络时收到的通知:
wlan_notification_acm_profile_change
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_connection_start
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_scan_fail
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_connection_complete
忽略中间通知代码,处理 wlan_notification_acm_connection_complete 和 wlan_notification_acm_disconnected 将起作用。
我想知道 windows C++ 应用程序如何在 windows 系统更改其 wifi 网络时收到通知。我对以下案例感兴趣:
- 当用户打开 wifi 并连接到新网络时
- 当用户关闭 wifi 并断开与网络的连接时
- 当用户从网络A切换到网络B时
注:切换on/off wifi 不感兴趣。设备需要连接到网络。网络可能有也可能没有互联网连接。
我正在尝试使用 wlanapi.h and have checked out a few examples 实现此目的,但未能实现。
让我知道是否有人能够使用 wlanapi.h 实现此目的。还是有另一种方法?请举例说明。
如有任何帮助,我们将不胜感激。
编辑:添加代码
#include <windows.h>
#include <Wlanapi.h>
#include <iostream>
// Link wlanapi.lib
#pragma comment(lib, "wlanapi.lib")
void DetectWifiNetworkChanges ();
void EventLoop ();
// Callback func to receive network notifications
void WlanNotificationCallback (PWLAN_NOTIFICATION_DATA pData, PVOID pContext);
int main ()
{
DetectWifiNetworkChanges ();
printf ("\n");
getchar ();
return 0;
}
void DetectWifiNetworkChanges ()
{
printf ("DetectWifiNetworkChanges\n");
HANDLE client;
DWORD client_version = 2;
DWORD current_version = 0;
DWORD result;
result = WlanOpenHandle (client_version, NULL, ¤t_version, &client);
if (result != ERROR_SUCCESS) {
printf ("WlanOpenHandle failed !!\n");
return;
}
result = WlanRegisterNotification (client, WLAN_NOTIFICATION_SOURCE_ALL, FALSE, WlanNotificationCallback, NULL, NULL, NULL);
if (result != ERROR_SUCCESS) {
printf ("WlanRegisterNotification failed !!\n");
return;
}
printf ("WlanRegistration successful\n");
// An infinite loop (Ctrl + C to quit the app for now)
EventLoop ();
result = WlanCloseHandle (client, NULL);
if (result != ERROR_SUCCESS) {
printf ("WlanCloseHandle !!\n");
return;
}
}
输出
DetectWifiNetworkChanges
WlanRegistration successful
EventLoop
我尝试连接和断开我的网络,但没有调用回调。
但有时,在我没有断开网络连接的情况下,回调会被调用很多次。
解决方法很简单。 我只需要在注册和捕获回调中的状态时更改通知类型(之前回调为空)。
当registering时,通知源应该是WLAN_NOTIFICATION_SOURCE_ACM。
我捕获了回调中的所有 states。 这是修改后的工作代码
#include <windows.h>
#include <Wlanapi.h>
#include <iostream>
// Link wlanapi.lib
#pragma comment(lib, "wlanapi.lib")
void DetectWifiNetworkChanges ();
void HandleACMNotifications (PWLAN_NOTIFICATION_DATA pNotification);
// Callback func to receive wifi notifications
void WlanNotificationCallback (PWLAN_NOTIFICATION_DATA pData, PVOID pContext);
int
main ()
{
DetectWifiNetworkChanges ();
printf ("\n");
getchar ();
return 0;
}
// Entry point.
// Will be called from int main
void
DetectWifiNetworkChanges ()
{
printf ("DetectWifiNetworkChanges\n");
HANDLE client;
DWORD client_version = 2;
DWORD current_version = 0;
DWORD result;
result = WlanOpenHandle (client_version, NULL, ¤t_version, &client);
if (result != ERROR_SUCCESS) {
printf ("WlanOpenHandle failed !!\n");
return;
}
result = WlanRegisterNotification (client, WLAN_NOTIFICATION_SOURCE_ACM, FALSE, WlanNotificationCallback, NULL, NULL, NULL);
if (result != ERROR_SUCCESS) {
printf ("WlanRegisterNotification failed !!\n");
return;
}
printf ("WlanRegistration successful\n");
// Wait for input from user
// The program pauses here. Toggle the wifi, change wifi network etc.
// to see the wifi notifications
getchar ();
result = WlanCloseHandle (client, NULL);
if (result != ERROR_SUCCESS) {
printf ("WlanCloseHandle !!\n");
return;
}
}
void
WlanNotificationCallback (PWLAN_NOTIFICATION_DATA pNotification, PVOID pContext)
{
printf ("WlanNotificationCallback\n");
if (pNotification->NotificationSource == WLAN_NOTIFICATION_SOURCE_ACM)
HandleACMNotifications (pNotification);
}
void
HandleACMNotifications (PWLAN_NOTIFICATION_DATA pNotification)
{
printf ("HandleACMNotifications\n");
switch (pNotification->NotificationCode) {
case wlan_notification_acm_start:
printf ("wlan_notification_acm_start\n");
break;
case wlan_notification_acm_autoconf_enabled:
printf ("wlan_notification_acm_autoconf_enabled\n");
break;
case wlan_notification_acm_autoconf_disabled:
printf ("wlan_notification_acm_autoconf_disabled\n");
break;
case wlan_notification_acm_background_scan_enabled:
printf ("wlan_notification_acm_background_scan_enabled\n");
break;
case wlan_notification_acm_background_scan_disabled:
printf ("wlan_notification_acm_background_scan_disabled\n");
break;
case wlan_notification_acm_bss_type_change:
printf ("wlan_notification_acm_bss_type_change\n");
break;
case wlan_notification_acm_power_setting_change:
printf ("wlan_notification_acm_power_setting_change\n");
break;
case wlan_notification_acm_scan_complete:
printf ("wlan_notification_acm_scan_complete\n");
break;
case wlan_notification_acm_scan_fail:
printf ("wlan_notification_acm_scan_fail\n");
break;
case wlan_notification_acm_connection_start:
printf ("wlan_notification_acm_connection_start\n");
break;
case wlan_notification_acm_connection_complete:
printf ("wlan_notification_acm_connection_complete\n");
break;
case wlan_notification_acm_connection_attempt_fail:
printf ("wlan_notification_acm_connection_attempt_fail\n");
break;
case wlan_notification_acm_filter_list_change:
printf ("wlan_notification_acm_filter_list_change\n");
break;
case wlan_notification_acm_interface_arrival:
printf ("wlan_notification_acm_interface_arrival\n");
break;
case wlan_notification_acm_interface_removal:
printf ("wlan_notification_acm_interface_removal\n");
break;
case wlan_notification_acm_profile_change:
printf ("wlan_notification_acm_profile_change\n");
break;
case wlan_notification_acm_profile_name_change:
printf ("wlan_notification_acm_profile_name_change\n");
break;
case wlan_notification_acm_profiles_exhausted:
printf ("wlan_notification_acm_profiles_exhausted\n");
break;
case wlan_notification_acm_network_not_available:
printf ("wlan_notification_acm_network_not_available\n");
break;
case wlan_notification_acm_network_available:
printf ("wlan_notification_acm_network_available\n");
break;
case wlan_notification_acm_disconnecting:
printf ("wlan_notification_acm_disconnecting\n");
break;
case wlan_notification_acm_disconnected:
printf ("wlan_notification_acm_disconnected\n");
break;
case wlan_notification_acm_adhoc_network_state_change:
printf ("wlan_notification_acm_adhoc_network_state_change\n");
break;
case wlan_notification_acm_profile_unblocked:
printf ("wlan_notification_acm_profile_unblocked\n");
break;
case wlan_notification_acm_screen_power_change:
printf ("wlan_notification_acm_screen_power_change\n");
break;
case wlan_notification_acm_profile_blocked:
printf ("wlan_notification_acm_profile_blocked\n");
break;
case wlan_notification_acm_scan_list_refresh:
printf ("wlan_notification_acm_scan_list_refresh\n");
break;
case wlan_notification_acm_operational_state_change:
printf ("wlan_notification_acm_operational_state_change\n");
break;
case wlan_notification_acm_end:
printf ("wlan_notification_acm_end\n");
break;
}
}
观察:
当我点击 wifi 图标查看可用网络列表时,调用回调并显示以下通知
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_scan_complete
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_scan_list_refresh
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_network_available
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_profiles_exhausted
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_network_available
注意:WlanNotificationCallback、HandleACMNotifications是我的printfs,如代码所示。根据流程将这两个与通知代码一起粘贴在输出中。
由于系统会在以下情况下扫描并显示可用网络列表,因此将重复这些通知
- 当点击 wifi 图标选择并连接网络时
- 当与网络断开连接时和可用网络列表 再次可见。
断开网络时收到的通知:
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_scan_complete
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_scan_list_refresh
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_profile_change
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_disconnecting
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_disconnected
连接到网络时收到的通知:
wlan_notification_acm_profile_change
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_connection_start
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_scan_fail
WlanNotificationCallback
HandleACMNotifications
wlan_notification_acm_connection_complete
忽略中间通知代码,处理 wlan_notification_acm_connection_complete 和 wlan_notification_acm_disconnected 将起作用。