Windows 中的 Wifi 通知

Posted

技术标签:

【中文标题】Windows 中的 Wifi 通知【英文标题】:Wifi notifications in Windows 【发布时间】:2021-11-29 01:54:18 【问题描述】:

我想知道 Windows C++ 应用程序如何在 Windows 系统更改其 wifi 网络时收到通知。我对以下情况感兴趣:

    当用户打开 wifi 并连接到新网络时 当用户关闭 wifi 并与网络断开连接时 当用户从网络 A 更改为网络 B 时

注意:打开/关闭 wifi 并不重要。设备需要连接到网络。网络可能有也可能没有互联网连接。

我正在尝试使用wlanapi.h 来实现这一目标,并查看了一些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, &current_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

我尝试连接和断开网络,但未调用回调。

但有时,在我没有断开网络连接的情况下,回调会被调用很多次。

【问题讨论】:

“但没能做到这一点。” 您具体尝试了什么,出了什么问题。显示您尝试过的一些代码。 The WlanRegisterNotification function is used to register and unregister notifications on all wireless interfaces. @πάνταῥεῖ 我已经添加了代码。我确信我对图书馆的理解存在很大差距。我已经为此旋转了很长时间。我希望能理解这个问题。 【参考方案1】:

解决方案很简单。 我只需要在注册和捕获回调中的状态时更改通知的类型(之前的回调是空的)。

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, &current_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 中的 Wifi 通知的主要内容,如果未能解决你的问题,请参考以下文章

Windows 10 WiFi 配置文件是不是支持密码中的空白?

查看Windows电脑,已连接中的WiFi密码

查看Windows电脑,已连接中的WiFi密码

查看Windows电脑,已连接中的WiFi密码

查看Windows电脑,已连接中的WiFi密码

windows10怎样创建vpn连接