WlanAPI WiFi连接问题:崩溃、SSID赋值及密码设置求助
Windows XP下MinGW编译WlanAPI WiFi连接问题解决方案
1. 修复PDOT11_SSID赋值崩溃问题
崩溃核心原因是内存未正确分配或SSID长度/内容拷贝逻辑错误。PDOT11_SSID是指向DOT11_SSID结构体的指针,不能直接赋值字符串,必须先初始化结构体、设置长度再拷贝内容:
// 正确的SSID赋值方式 DOT11_SSID ssid; ZeroMemory(&ssid, sizeof(DOT11_SSID)); const char* target_ssid = "YourWiFiSSID"; ssid.uSSIDLength = strlen(target_ssid); memcpy(ssid.ucSSID, target_ssid, ssid.uSSIDLength); PDOT11_SSID pSsid = &ssid; // 直接取栈上结构体地址,无需动态分配
MinGW下需注意结构体对齐,可在头文件引入前添加:
#pragma pack(push, 1) #include <wlanapi.h> #pragma pack(pop)
2. 目标SSID密码的设置方法
Windows XP下连接加密WiFi(如WPA-PSK/WPA2-PSK),需通过XML配置文件传递密码,核心代码示例:
// 生成WPA2-PSK加密的配置文件内容 char profileXml[1024]; const char* wifi_password = "YourWiFiPassword"; snprintf(profileXml, sizeof(profileXml), "<?xml version=\"1.0\"?>" "<WLANProfile xmlns=\"http://www.microsoft.com/networking/WLAN/profile/v1\">" "<name>%s</name>" "<SSIDConfig>" "<SSID><name>%s</name></SSID>" "</SSIDConfig>" "<connectionType>ESS</connectionType>" "<connectionMode>auto</connectionMode>" "<MSM>" "<security>" "<authEncryption>" "<authentication>WPA2PSK</authentication>" "<encryption>AES</encryption>" "<useOneX>false</useOneX>" "</authEncryption>" "<sharedKey>" "<keyType>passPhrase</keyType>" "<protected>true</protected>" "<keyMaterial>%s</keyMaterial>" "</sharedKey>" "</security>" "</MSM>" "</WLANProfile>", target_ssid, target_ssid, wifi_password);
将该XML字符串传入WLAN_CONNECTION_PARAMETERS的strProfile字段即可。
3. 正确选择外接WiFi适配器接口
枚举所有WiFi适配器,通过接口描述筛选外接设备(如包含"Wireless"、"WiFi"关键词):
WLAN_INTERFACE_INFO_LIST* pIfList = NULL; DWORD dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList); if (dwResult != ERROR_SUCCESS) { /* 错误处理 */ } // 遍历并筛选适配器 for (DWORD i = 0; i < pIfList->dwNumberOfItems; i++) { WLAN_INTERFACE_INFO ifInfo = pIfList->InterfaceInfo[i]; printf("适配器%d: %s, GUID: %ws\n", i, ifInfo.strInterfaceDescription, ifInfo.InterfaceGuid); // 自动筛选外接WiFi适配器 if (strstr(ifInfo.strInterfaceDescription, "Wireless") != NULL) { GUID targetInterfaceGuid = ifInfo.InterfaceGuid; break; } } WlanFreeMemory(pIfList);
若无法自动筛选,可手动打印所有适配器信息,选择对应外接设备的GUID。
完整可运行代码示例
#pragma pack(push, 1) #include <windows.h> #include <wlanapi.h> #include <stdio.h> #include <string.h> #pragma pack(pop) // MinGW编译命令:gcc wifi_connect.c -o wifi_connect.exe -lwlanapi int main() { DWORD dwVersion = 0; HANDLE hClient = NULL; DWORD dwResult = WlanOpenHandle(2, NULL, &dwVersion, &hClient); if (dwResult != ERROR_SUCCESS) { printf("WlanOpenHandle失败,错误码: %d\n", dwResult); return 1; } // 枚举WiFi适配器 WLAN_INTERFACE_INFO_LIST* pIfList = NULL; dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList); if (dwResult != ERROR_SUCCESS || pIfList->dwNumberOfItems == 0) { printf("未找到可用WiFi适配器,错误码: %d\n", dwResult); WlanCloseHandle(hClient, NULL); return 1; } // 选择第一个WiFi适配器(可根据需求修改筛选逻辑) GUID targetGuid = pIfList->InterfaceInfo[0].InterfaceGuid; printf("选中适配器: %s\n", pIfList->InterfaceInfo[0].strInterfaceDescription); WlanFreeMemory(pIfList); // 初始化SSID DOT11_SSID ssid; ZeroMemory(&ssid, sizeof(DOT11_SSID)); const char* target_ssid = "TestWiFi"; ssid.uSSIDLength = strlen(target_ssid); memcpy(ssid.ucSSID, target_ssid, ssid.uSSIDLength); // 生成加密配置文件 char profileXml[1024]; const char* wifi_password = "TestPassword123"; snprintf(profileXml, sizeof(profileXml), "<?xml version=\"1.0\"?>" "<WLANProfile xmlns=\"http://www.microsoft.com/networking/WLAN/profile/v1\">" "<name>%s</name>" "<SSIDConfig>" "<SSID><name>%s</name></SSID>" "</SSIDConfig>" "<connectionType>ESS</connectionType>" "<connectionMode>auto</connectionMode>" "<MSM>" "<security>" "<authEncryption>" "<authentication>WPA2PSK</authentication>" "<encryption>AES</encryption>" "<useOneX>false</useOneX>" "</authEncryption>" "<sharedKey>" "<keyType>passPhrase</keyType>" "<protected>true</protected>" "<keyMaterial>%s</keyMaterial>" "</sharedKey>" "</security>" "</MSM>" "</WLANProfile>", target_ssid, target_ssid, wifi_password); // 配置连接参数 WLAN_CONNECTION_PARAMETERS connParams; ZeroMemory(&connParams, sizeof(WLAN_CONNECTION_PARAMETERS)); connParams.wlanConnectionMode = wlan_connection_mode_profile; connParams.strProfile = profileXml; connParams.pDot11Ssid = &ssid; connParams.dot11BssType = dot11_BSS_type_infrastructure; connParams.dwFlags = 0; // 连接隐藏SSID时改为WLAN_CONNECTION_HIDDEN_NETWORK // 发起连接 dwResult = WlanConnect(hClient, &targetGuid, &connParams, NULL); if (dwResult == ERROR_SUCCESS) { printf("连接请求已发送,正在连接...\n"); } else { printf("WlanConnect失败,错误码: %d\n", dwResult); } WlanCloseHandle(hClient, NULL); return 0; }
编译与运行注意事项
- MinGW编译必须链接
wlanapi库,命令:gcc wifi_connect.c -o wifi_connect.exe -lwlanapi - 程序需以管理员权限运行,否则会出现权限不足错误。
- Windows XP需安装SP3补丁,以支持WPA2-PSK加密。
内容的提问来源于stack exchange,提问作者C.Unbay
相关产品推荐
相关产品推荐

