文章目录
- 什么是WLAN呢?
- 命令行操作WLAN
- WLAN列表
- 连接WLAN
- 断开WLAN
- 使用 Win api
- 获取所有WLAN列表
- 连接WLAN
- 设置密码
- 断开连接
- Java代码操作
Hello, I’m Shendi.
在编写的时候文章莫名其妙乱了,以至于修改了一遍,可能有些地方代码中使用的字符是中文字符,稍作修改即可
什么是WLAN呢?
WLAN是无线局域网的简称。
指应用无线通信技术将计算机设备互联起来,构成可以互相通信和实现资源共享的网络体系命令行操作WLAN
WLAN列表
netsh wlan show networks
连接WLAN
在连接WLAN时需要使用到配置文件
首先通过命令查询已有配置文件列表
netsh wlan show profile
先导出一个已有的配置文件看一下内容
使用命令
netsh wlan export profile key=clear
key=clear为明文方式显示密码
导出单个配置文件为
netsh wlan export profile 配置文件 key=clear默认保存在当前cmd目录下

内容如下
<?xml version="1.0"?>
<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1">
<name>配置文件名</name>
<SSIDConfig>
<SSID>
<hex>(此项可无)</hex>
<name>WLAN名称</name>
</SSID>
<nonBroadcast>false</nonBroadcast>
</SSIDConfig>
<connectionType>ESS</connectionType>
<connectionMode>manual</connectionMode>
<autoSwitch>false</autoSwitch>
<MSM>
<security>
<authEncryption>
<authentication>WPA2PSK</authentication>
<encryption>AES</encryption>
<useOneX>false</useOneX>
</authEncryption>
<sharedKey>
<keyType>passPhrase</keyType>
<protected>false</protected>
<keyMaterial>WLAN密码</keyMaterial>
</sharedKey>
</security>
</MSM>
</WLANProfile>可以通过修改配置文件来指定连接的WLAN和对应密码
更改此配置文件,保存,使用以下命令将配置导入
netsh wlan add profile filename="配置文件名.xml"
最后,使用connect命令进行连接操作
netsh wlan connect name="Shendi"
这里的name为配置文件名
执行后可以看到已经连上指定WLAN了

断开WLAN
使用命令
netsh wlan disconnect
在知道流程后,也可以通过使用代码的方式模拟执行以上操作,比较繁琐,这里就不举例了
使用 Win api
可以直接使用代码的方式来操作当然是首选了,我使用的Windows操作系统,于是使用Native Wifi
可以直接看API文档
获取所有WLAN列表
使用到 wlanapi.h 中的 WlanGetAvailableNetworkList
可以参考文档,文档最下方有一个举例,这里直接copy过来(C++)
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <wlanapi.h>
#include <objbase.h>
#include <wtypes.h>
#include <stdio.h>
#include <stdlib.h>
// Need to link with Wlanapi.lib and Ole32.lib
#pragma comment(lib, "wlanapi.lib")
#pragma comment(lib, "ole32.lib")
int wmain()
{
// Declare and initialize variables.
HANDLE hClient = NULL;
DWORD dwMaxClient = 2; //
DWORD dwCurVersion = 0;
DWORD dwResult = 0;
DWORD dwRetVal = 0;
int iRet = 0;
WCHAR GuidString[39] = {0};
unsigned int i, j, k;
/* variables used for WlanEnumInterfaces */
PWLAN_INTERFACE_INFO_LIST pIfList = NULL;
PWLAN_INTERFACE_INFO pIfInfo = NULL;
PWLAN_AVAILABLE_NETWORK_LIST pBssList = NULL;
PWLAN_AVAILABLE_NETWORK pBssEntry = NULL;
int iRSSI = 0;
dwResult = WlanOpenHandle(dwMaxClient, NULL, &dwCurVersion, &hClient);
if (dwResult != ERROR_SUCCESS) {
wprintf(L"WlanOpenHandle failed with error: %u\n", dwResult);
return 1;
// You can use FormatMessage here to find out why the function failed
}
dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList);
if (dwResult != ERROR_SUCCESS) {
wprintf(L"WlanEnumInterfaces failed with error: %u\n", dwResult);
return 1;
// You can use FormatMessage here to find out why the function failed
} else {
wprintf(L"Num Entries: %lu\n", pIfList->dwNumberOfItems);
wprintf(L"Current Index: %lu\n", pIfList->dwIndex);
for (i = 0; i < (int) pIfList->dwNumberOfItems; i++) {
pIfInfo = (WLAN_INTERFACE_INFO *) &pIfList->InterfaceInfo[i];
wprintf(L" Interface Index[%u]:\t %lu\n", i, i);
iRet = StringFromGUID2(pIfInfo->InterfaceGuid, (LPOLESTR) &GuidString,
sizeof(GuidString)/sizeof(*GuidString));
// For c rather than C++ source code, the above line needs to be
// iRet = StringFromGUID2(&pIfInfo->InterfaceGuid, (LPOLESTR) &GuidString,
// sizeof(GuidString)/sizeof(*GuidString));
if (iRet == 0)
wprintf(L"StringFromGUID2 failed\n");
else {
wprintf(L" InterfaceGUID[%d]: %ws\n",i, GuidString);
}
wprintf(L" Interface Description[%d]: %ws", i,
pIfInfo->strInterfaceDescription);
wprintf(L"\n");
wprintf(L" Interface State[%d]:\t ", i);
switch (pIfInfo->isState) {
case wlan_interface_state_not_ready:
wprintf(L"Not ready\n");
break;
case wlan_interface_state_connected:
wprintf(L"Connected\n");
break;
case wlan_interface_state_ad_hoc_network_formed:
wprintf(L"First node in a ad hoc network\n");
break;
case wlan_interface_state_disconnecting:
wprintf(L"Disconnecting\n");
break;
case wlan_interface_state_disconnected:
wprintf(L"Not connected\n");
break;
case wlan_interface_state_associating:
wprintf(L"Attempting to associate with a network\n");
break;
case wlan_interface_state_discovering:
wprintf(L"Auto configuration is discovering settings for the network\n");
break;
case wlan_interface_state_authenticating:
wprintf(L"In process of authenticating\n");
break;
default:
wprintf(L"Unknown state %ld\n", pIfInfo->isState);
break;
}
wprintf(L"\n");
dwResult = WlanGetAvailableNetworkList(hClient,
&pIfInfo->InterfaceGuid,
0,
NULL,
&pBssList);
if (dwResult != ERROR_SUCCESS) {
wprintf(L"WlanGetAvailableNetworkList failed with error: %u\n",
dwResult);
dwRetVal = 1;
// You can use FormatMessage to find out why the function failed
} else {
wprintf(L"WLAN_AVAILABLE_NETWORK_LIST for this interface\n");
wprintf(L" Num Entries: %lu\n\n", pBssList->dwNumberOfItems);
for (j = 0; j < pBssList->dwNumberOfItems; j++) {
pBssEntry =
(WLAN_AVAILABLE_NETWORK *) & pBssList->Network[j];
wprintf(L" Profile Name[%u]: %ws\n", j, pBssEntry->strProfileName);
wprintf(L" SSID[%u]:\t\t ", j);
if (pBssEntry->dot11Ssid.uSSIDLength == 0)
wprintf(L"\n");
else {
for (k = 0; k < pBssEntry->dot11Ssid.uSSIDLength; k++) {
wprintf(L"%c", (int) pBssEntry->dot11Ssid.ucSSID[k]);
}
wprintf(L"\n");
}
wprintf(L" BSS Network type[%u]:\t ", j);
switch (pBssEntry->dot11BssType) {
case dot11_BSS_type_infrastructure :
wprintf(L"Infrastructure (%u)\n", pBssEntry->dot11BssType);
break;
case dot11_BSS_type_independent:
wprintf(L"Infrastructure (%u)\n", pBssEntry->dot11BssType);
break;
default:
wprintf(L"Other (%lu)\n", pBssEntry->dot11BssType);
break;
}
wprintf(L" Number of BSSIDs[%u]:\t %u\n", j, pBssEntry->uNumberOfBssids);
wprintf(L" Connectable[%u]:\t ", j);
if (pBssEntry->bNetworkConnectable)
wprintf(L"Yes\n");
else {
wprintf(L"No\n");
wprintf(L" Not connectable WLAN_REASON_CODE value[%u]:\t %u\n", j,
pBssEntry->wlanNotConnectableReason);
}
wprintf(L" Number of PHY types supported[%u]:\t %u\n", j, pBssEntry->uNumberOfPhyTypes);
if (pBssEntry->wlanSignalQuality == 0)
iRSSI = -100;
else if (pBssEntry->wlanSignalQuality == 100)
iRSSI = -50;
else
iRSSI = -100 + (pBssEntry->wlanSignalQuality/2);
wprintf(L" Signal Quality[%u]:\t %u (RSSI: %i dBm)\n", j,
pBssEntry->wlanSignalQuality, iRSSI);
wprintf(L" Security Enabled[%u]:\t ", j);
if (pBssEntry->bSecurityEnabled)
wprintf(L"Yes\n");
else
wprintf(L"No\n");
wprintf(L" Default AuthAlgorithm[%u]: ", j);
switch (pBssEntry->dot11DefaultAuthAlgorithm) {
case DOT11_AUTH_ALGO_80211_OPEN:
wprintf(L"802.11 Open (%u)\n", pBssEntry->dot11DefaultAuthAlgorithm);
break;
case DOT11_AUTH_ALGO_80211_SHARED_KEY:
wprintf(L"802.11 Shared (%u)\n", pBssEntry->dot11DefaultAuthAlgorithm);
break;
case DOT11_AUTH_ALGO_WPA:
wprintf(L"WPA (%u)\n", pBssEntry->dot11DefaultAuthAlgorithm);
break;
case DOT11_AUTH_ALGO_WPA_PSK:
wprintf(L"WPA-PSK (%u)\n", pBssEntry->dot11DefaultAuthAlgorithm);
break;
case DOT11_AUTH_ALGO_WPA_NONE:
wprintf(L"WPA-None (%u)\n", pBssEntry->dot11DefaultAuthAlgorithm);
break;
case DOT11_AUTH_ALGO_RSNA:
wprintf(L"RSNA (%u)\n", pBssEntry->dot11DefaultAuthAlgorithm);
break;
case DOT11_AUTH_ALGO_RSNA_PSK:
wprintf(L"RSNA with PSK(%u)\n", pBssEntry->dot11DefaultAuthAlgorithm);
break;
default:
wprintf(L"Other (%lu)\n", pBssEntry->dot11DefaultAuthAlgorithm);
break;
}
wprintf(L" Default CipherAlgorithm[%u]: ", j);
switch (pBssEntry->dot11DefaultCipherAlgorithm) {
case DOT11_CIPHER_ALGO_NONE:
wprintf(L"None (0x%x)\n", pBssEntry->dot11DefaultCipherAlgorithm);
break;
case DOT11_CIPHER_ALGO_WEP40:
wprintf(L"WEP-40 (0x%x)\n", pBssEntry->dot11DefaultCipherAlgorithm);
break;
case DOT11_CIPHER_ALGO_TKIP:
wprintf(L"TKIP (0x%x)\n", pBssEntry->dot11DefaultCipherAlgorithm);
break;
case DOT11_CIPHER_ALGO_CCMP:
wprintf(L"CCMP (0x%x)\n", pBssEntry->dot11DefaultCipherAlgorithm);
break;
case DOT11_CIPHER_ALGO_WEP104:
wprintf(L"WEP-104 (0x%x)\n", pBssEntry->dot11DefaultCipherAlgorithm);
break;
case DOT11_CIPHER_ALGO_WEP:
wprintf(L"WEP (0x%x)\n", pBssEntry->dot11DefaultCipherAlgorithm);
break;
default:
wprintf(L"Other (0x%x)\n", pBssEntry->dot11DefaultCipherAlgorithm);
break;
}
wprintf(L" Flags[%u]:\t 0x%x", j, pBssEntry->dwFlags);
if (pBssEntry->dwFlags) {
if (pBssEntry->dwFlags & WLAN_AVAILABLE_NETWORK_CONNECTED)
wprintf(L" - Currently connected");
if (pBssEntry->dwFlags & WLAN_AVAILABLE_NETWORK_HAS_PROFILE)
wprintf(L" - Has profile");
}
wprintf(L"\n");
wprintf(L"\n");
}
}
}
}
if (pBssList != NULL) {
WlanFreeMemory(pBssList);
pBssList = NULL;
}
if (pIfList != NULL) {
WlanFreeMemory(pIfList);
pIfList = NULL;
}
return dwRetVal;
}运行后会看到控制台打印了现在范围内的一些WLAN列表的一些信息了

虽然上面代码很多,但是只用到了四个函数,解释一下上面的代码
引入文件
#include <windows.h>
#include <wlanapi.h>
#include <objbase.h>
#include <wtypes.h>
#include <stdio.h>
#include <stdlib.h>
// Need to link with Wlanapi.lib and Ole32.lib
#pragma comment(lib, "wlanapi.lib")
#pragma comment(lib, "ole32.lib")首先使用到WlanOpenHnadle打开一个句柄
文档
然后使用WlanEnumInterfaces获取无线网卡列表

获取到的为结构体PWLAN_INTERFACE_INFO_LIST
其中使用 InterfaceInfo 的形式来取出 PWLAN_INTERFACE_INFO
最后使用 WlanGetAvailableNetworkList 函数获取无线LAN接口上有效网络信息
文档WLAN_AVAILABLE_NETWORK_LIST文档WLAN_AVAILABLE_NETWORK文档 最后使用WlanFreeMemory释放List
代码如下
#include <windows.h>
#include <wlanapi.h>
#include <objbase.h>
#include <wtypes.h>
#include <stdio.h>
#include <stdlib.h>
// Need to link with Wlanapi.lib and Ole32.lib
#pragma comment(lib, "wlanapi.lib")
#pragma comment(lib, "ole32.lib")
int main() {
/*
WlanOpenHandle 函数
该WlanOpenHandle功能打开到服务器的连接。
四个参数 分别为
_In_ DWORD dwClientVersion,
客户端支持的最高版本WLAN API,1(Win xp或者Win xp sp2)/2(一般用这个Win vista或Win server 2008)
_Reserved_ PVOID pReserved,保留参数,填NULL就行
_Out_ PDWORD pdwNegotiatedVersion,
在此会话中使用的WLAN API版本,通常是客户端和服务器都支持的最高版本,官方demo填的是0,此参数为指针
_Out_ PHANDLE phClientHandle
客户端在此会话中使用的句柄,整个会话中,其他功能都使用此句柄,此参数为指针
返回码
ERROR_SUCCESS 函数执行成功
ERROR_INVALID_PARAMETER pdwNegotiatedVersion是NULL,phClientHandle为NULL,或保留不空。
ERROR_NOT_ENOUGH_MEMORY 无法分配内存来创建客户端上下文。
RPC_STATUS 各种错误代码。
ERROR_REMOTE_SESSION_LIMIT_EXCEEDED 服务器已发出过多的句柄。
*/
// 这里两个参数是必须的,传递方式也是如此,否则会出ERROR_INVALID_PARAMETER,可能与函数重载有关
// 打开的句柄
HANDLE ch = NULL;
DWORD useVersion = 0;
DWORD dwResult = WlanOpenHandle(2, NULL, &useVersion, &ch);
if (dwResult != ERROR_SUCCESS) {
const char* error = NULL;
switch (dwResult) {
case ERROR_INVALID_PARAMETER:
error = "ERROR_INVALID_PARAMETER";
break;
case ERROR_NOT_ENOUGH_MEMORY:
error = "ERROR_NOT_ENOUGH_MEMORY";
break;
case ERROR_REMOTE_SESSION_LIMIT_EXCEEDED:
error = "ERROR_REMOTE_SESSION_LIMIT_EXCEEDED";
break;
}
printf("WlanOpenHandle函数执行失败,错误码为: %s", error);
return 0;
}
/*
WlanEnumInterfaces函数枚举所有的本地计算机上当前启用的无限LAN接口
三个参数 分别为
HANDLE hClientHandle,
客户端会话句柄,由先前对WlanOpenHandle函数调用获得
PVOID pReserved,
保留参数,必须填NULL
PWLAN_INTERFACE_INFO_LIST *ppInterfaceList
该指针用以WLAN_INTERFACE_INFO_LIST结构接收返回的无限LAN的列表
如果调用成功则由WLANEnumInterface函数分配返回的WLAN_INTERFACE_INFO_LIST缓冲区
返回码
ERROR_SUCCESS 函数执行成功
ERROR_INVALID_PARAMETER
如果hClientHandle或ppInterfaceList参数为NULL,
如果pReserved不为NULL
如果hClientHandle参数无效
ERROR_INVALID_HANDLE 在句柄表中找不到 句柄hClientHandle。
ERROR_NOT_ENOUGH_MEMORY 没有足够的内存来处理此请求并为查询结果分配内存
*/
/*
list中有三个参数
dwIndex 索引
dwNumberOfItems 集合内元素数
interfaceInfo 具体元素数组
*/
PWLAN_INTERFACE_INFO_LIST list = NULL;
dwResult = WlanEnumInterfaces(ch, NULL, &list);
if (dwResult != ERROR_SUCCESS) {
const char* error = NULL;
switch (dwResult) {
case ERROR_INVALID_PARAMETER:
error = "ERROR_INVALID_PARAMETER";
break;
case ERROR_INVALID_HANDLE:
error = "ERROR_INVALID_HANDLE";
break;
case ERROR_NOT_ENOUGH_MEMORY:
error = "ERROR_NOT_ENOUGH_MEMORY";
break;
}
printf("WlanEnumInterfaces函数执行失败,错误码为: %s", error);
return 0;
}
// WLANGetAvailabelNetworkList函数调用时候的列表,与上一个List相同,但第三个参数变成了Network
PWLAN_AVAILABLE_NETWORK_LIST lanList = NULL;
// 遍历网卡接口集合,我电脑只有一个无线网卡
int len = list->dwNumberOfItems;//=1
PWLAN_INTERFACE_INFO lanInfo = NULL;
for (int i = 0; i < len; i++) {
// 取出
lanInfo = &list->InterfaceInfo[i];
// 网卡状态获取
const char* lanState = NULL;
switch (lanInfo->isState) {
case wlan_interface_state_not_ready:
lanState = "Not ready";
break;
case wlan_interface_state_connected:
lanState = "Connected";
break;
case wlan_interface_state_ad_hoc_network_formed:
lanState = "First node in a ad hoc network";
break;
case wlan_interface_state_disconnecting:
lanState = "Disconnecting";
break;
case wlan_interface_state_disconnected:
lanState = "Not connected";
break;
case wlan_interface_state_associating:
lanState = "Attempting to associate with a network";
break;
case wlan_interface_state_discovering:
lanState = "Auto configuration is discovering settings for the network";
break;
case wlan_interface_state_authenticating:
lanState = "In process of authenticating";
break;
default:
lanState = "Unknown state " + lanInfo->isState;
break;
}
// GUID
WCHAR lanGUID[39];
StringFromGUID2(lanInfo->InterfaceGuid, (LPOLESTR)&lanGUID, sizeof(lanGUID) / sizeof(*lanGUID));
printf("网卡 %ws 信息\n状态: %s\nGUID: %ws\n------------------", lanInfo->strInterfaceDescription, lanState, lanGUID);
/*
WLANGetAvailabelNetworkList函数 获取无线LAN接口上的可用网络列表
HANDLE hClientHandle,
会话句柄,由先前WlanOpenHandle函数调用获得
const GUID *pInterfaceGuid,
指向要查询的无线LAN接口的GUID的指针,可以通过WLANEnumInterfaces函数确定无线LAN接口的GUID
DWORD dwFlags,
一组标志,用于控制列表中返回的网络类型,此参数可以是这些可能值的组合
WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_ADHOC_PROFILES 0x0
在可用网络列表中包括所有临时网络配置文件,包括不可见的配置文件
WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_MANUAL_HIDDEN_PROFILES 0x2
在可用网络列表中包括所有隐藏的网络配置文件,包括不可见的配置文件
注:如果在带有SP3的Windows XP和带有SP2的Windows XP的无线局域网API中指定了此标志,则将其视为无效参数
PVOID pReserved,
保留参数,必须为NULL
PWLAN_AVAILABLE_NETWORK_LIST *ppAvailableNetworkList
指向存储的指针,用于接收WLAN_AVAILABEL_NETWORK_LIST结构中返回的可见网络列表
返回码
ERROR_SUCCESS 函数执行成功
ERROR_INVALID_PARAMETER
如果hClientHandle,pInterfaceGuid或ppAvailableNetworkList参数为NULL
如果pReserved不为NULL
如果dwFlags参数值设置为无效值或hClientHandle参数无效
ERROR_INVALID_HANDLE 在句柄表中找不到 句柄hClientHandle。
ERROR_NDIS_DOT11_POWER_STATE_INVALID
与接口关联的无线电已关闭,无线电关闭时,没有可用的网络
RPC_STATUS 各种错误代码
ERROR_NOT_ENOUGH_MEMORY 没有足够的内存来处理此请求并为查询结果分配内存
*/
dwResult = WlanGetAvailableNetworkList(ch, &lanInfo->InterfaceGuid, 0, NULL, &lanList);
if (dwResult != ERROR_SUCCESS) {
const char* error = NULL;
switch (dwResult) {
case ERROR_INVALID_PARAMETER:
error = "ERROR_INVALID_PARAMETER";
break;
case ERROR_INVALID_HANDLE:
error = "ERROR_INVALID_HANDLE";
break;
case ERROR_NDIS_DOT11_POWER_STATE_INVALID:
error = "ERROR_NDIS_DOT11_POWER_STATE_INVALID";
break;
case ERROR_NOT_ENOUGH_MEMORY:
error = "ERROR_NOT_ENOUGH_MEMORY";
break;
}
printf("WlanGetAvailableNetworkList函数执行失败,错误码为: %s", error);
continue;
}
// 遍历无线网集合
int len = lanList->dwNumberOfItems;
PWLAN_AVAILABLE_NETWORK network = NULL;
for (int j = 0; j < len; j++) {
// 获取具体元素
network = &lanList->Network[j];
// WLAN名称
int size = network->dot11Ssid.uSSIDLength;
if (size == 0) {
continue;
}
char* name = (char*) malloc((size + 1) * sizeof(char));
// C语言字符串以\0结尾,在这个地方踩坑了...
name[size] = '\0';
for (int k = 0; k < size; k++) {
name[k] = network->dot11Ssid.ucSSID[k];
}
printf("---------------\n");
printf("[%d]\n关联的配置文件名称(无则空): %ws\nWLAN名称 : %s\n", j, network->strProfileName, name);
free(name);
name = NULL;
}
}
// 释放指针指向的内存,并释放指针
if (lanList != NULL) {
WlanFreeMemory(lanList);
lanList = NULL;
}
if (list != NULL) {
WlanFreeMemory(list);
list = NULL;
}
return 0;
}连接WLAN
使用WlanConnect函数文档
直接上代码
#include <windows.h>
#include <wlanapi.h>
#include <objbase.h>
#include <wtypes.h>
#include <stdio.h>
#include <stdlib.h>
// Need to link with Wlanapi.lib and Ole32.lib
#pragma comment(lib, "wlanapi.lib")
#pragma comment(lib, "ole32.lib")
int main() {
// 打开连接
HANDLE handle = NULL;
DWORD useVersion = 0;
DWORD result = WlanOpenHandle(2, NULL, &useVersion, &handle);
if (result != ERROR_SUCCESS) {
printf("WlanOpenHandle失败: %d", result);
return 0;
}
// 获取无线LAN接口,我这电脑只有一个无线LAN接口
PWLAN_INTERFACE_INFO_LIST list = NULL;
result = WlanEnumInterfaces(handle, NULL, &list);
if (result != ERROR_SUCCESS) {
printf("WlanEnumInterfaces失败: %d", result);
return 0;
}
PWLAN_INTERFACE_INFO info = &list->InterfaceInfo[0];
/*
WlanConnect函数 尝试连接到特定网络
参数
HANDLE hClientHandle,
客户端句柄,由WlanOpenHandle获取
const GUID *pInterfaceGuid,
接口GUID(之前WlanEnumInterfaces获取...)
const PWLAN_CONNECTION_PARAMETERS pConnectionParameters,
指向WLAN_CONNECTION_PARAMETERS结构的指针
该结构指定连接类型,模式,网络配置文件,标识网络的SSID以及其他参数
PVOID pReserved
保留参数,NULL
返回值
ERROR_SUCCESS 函数执行成功
ERROR_INVALID_PARAMETER 太多情况可触发,看文档
ERROR_INVALID_HANDLE 在句柄表中找不到 句柄hClientHandle
RPC_STATUS 各种错误代码。
ERROR_ACCESS_DENIED 呼叫者没有足够的权限
*/
WLAN_CONNECTION_PARAMETERS connParam;
// 连接模式
connParam.wlanConnectionMode = wlan_connection_mode_profile;
// 指定用于连接的配置文件
connParam.strProfile = L"401";
// 指示网络的BSS类型.如果提供了配置文件,则此BSS类型必须与配置文件中的类型相同
connParam.dot11BssType = dot11_BSS_type_infrastructure;
connParam.pDot11Ssid = NULL;
connParam.pDesiredBssidList = NULL;
// 用于指定连接参数的标志
connParam.dwFlags = WLAN_CONNECTION_HIDDEN_NETWORK;
result = WlanConnect(handle, &info->InterfaceGuid, &connParam, NULL);
if (result != ERROR_SUCCESS) {
printf("连接失败: %d", result);
} else {
printf("连接成功");
}
if (list != NULL) { WlanFreeMemory(list); }
return 0;
}需要注意的是传递的连接参数 WLAN_CONNECTION_PARAMETERS
上面所设置值少一项就出错,且我连接的是已有配置文件的WLAN
设置密码
对于设置密码,主要是操作配置文件
获取配置文件比较简单,这里直接放上文档,不做解释
WlanGetProfile文档WlanGetProfileList文档
设置配置文件使用WlanSetProfile
WlanSetProfile文档 对于配置文件内容,参考
WLANProfile元素文档
直接上代码
#include <windows.h>
#include <wlanapi.h>
#include <objbase.h>
#include <wtypes.h>
#include <stdio.h>
#include <stdlib.h>
// Need to link with Wlanapi.lib and Ole32.lib
#pragma comment(lib, "wlanapi.lib")
#pragma comment(lib, "ole32.lib")
// 设置并连接WLAN
int main() {
// 打开连接
DWORD useVersion = 0;
HANDLE handle = NULL;
PWLAN_INTERFACE_INFO_LIST list = NULL;
PWLAN_INTERFACE_INFO info;
// 配置文件内容
LPCWSTR xmlContent = L"<?xml version=\"1.0\"?><WLANProfile xmlns = \"http://www.microsoft.com/networking/WLAN/profile/v1\">"\
"<name>Shendi</name>"
"<SSIDConfig>"
"<SSID>"
"<name>Shendi</name>"
"</SSID>"
"<nonBroadcast>false</nonBroadcast>"
"</SSIDConfig>"
"<connectionType>ESS</connectionType>"
"<connectionMode>manual</connectionMode>"
"<autoSwitch>false</autoSwitch>"
"<MSM>"
"<security>"
"<authEncryption>"
"<authentication>WPA2PSK</authentication>"
"<encryption>AES</encryption>"
"<useOneX>false</useOneX>"
"</authEncryption>"
"<sharedKey>"
"<keyType>passPhrase</keyType>"
"<protected>false</protected>"
"<keyMaterial>12345678</keyMaterial>"
"</sharedKey>"
"</security>"
"</MSM>"
"</WLANProfile>";
DWORD result = WlanOpenHandle(2, NULL, &useVersion, &handle);
if (result != ERROR_SUCCESS) {
printf("WlanOpenHandle执行失败: %d", result);
goto exit;
}
// 获取无线LAN接口,我这电脑只有一个无线LAN接口
result = WlanEnumInterfaces(handle, NULL, &list);
if (result != ERROR_SUCCESS) {
printf("WlanEnumInterfaces失败: %d", result);
goto exit;
}
info = &list->InterfaceInfo[0];
/*
WlanSetProfile 设置特定的配置文件的内容
参数
HANDLE hClientHandle, 句柄
const GUID *pInterfaceGuid, 接口GUID
DWORD dwFlags, 标志
0 所有用户的配置文件
WLAN_PROFILE_GROUP_POLICY(0x1) 组策略配置
WLAN_PROFILE_USER(0x2) 每个用户的配置文件
LPCWSTR strProfileXml, 包含配置文件的XML表示形式
LPCWSTR strAllUserProfileSecurity, 在所有用户配置文件上设置安全描述符字符串,如果dwFlags设置为WLAN_PROFILE_USER,则忽略此参数
BOOL bOverwrite, 指定此配置文件是否覆盖现有的配置文件
PVOID pReserved, NULL
DWORD *pdwReasonCode 一个WLAN_REASON_CODE值,指示配置文件为什么是无效的
返回值
ERROR_SUCCESS 函数执行成功
ERROR_ACCESS_DENIED 没有权限
ERROR_ALREADY_EXISTS 配置已经存在,当bOverwrite为FALSE时使用此返回值
ERROR_BAD_PROFILE 指定配置无效
ERROR_INVALID_PARAMETER 参数有问题
ERROR_NO_MATCH 不支持配置文件中的一项或多项
RPC_STATUS 各种错误代码。
*/
DWORD reasonCode;
result = WlanSetProfile(handle, &info->InterfaceGuid, 0, xmlContent, NULL, true, NULL, &reasonCode);
if (result != ERROR_SUCCESS) {
printf("WlanSetProfile失败: %d", result);
goto exit;
}
// 连接网络
WLAN_CONNECTION_PARAMETERS connParam;
// 连接模式
connParam.wlanConnectionMode = wlan_connection_mode_profile;
// 指定用于连接的配置文件
connParam.strProfile = L"Shendi";
// 指示网络的BSS类型.如果提供了配置文件,则此BSS类型必须与配置文件中的类型相同
connParam.dot11BssType = dot11_BSS_type_infrastructure;
connParam.pDot11Ssid = NULL;
connParam.pDesiredBssidList = NULL;
// 用于指定连接参数的标志
connParam.dwFlags = WLAN_CONNECTION_HIDDEN_NETWORK;
result = WlanConnect(handle, &info->InterfaceGuid, &connParam, NULL);
if (result != ERROR_SUCCESS) {
printf("连接失败: %d", result);
} else {
// 这里的连接成功为函数执行成功,如果没有对应WLAN则无法连接,需要使用其他函数进行检测
printf("连接成功");
}
exit:
// 关闭句柄,释放资源
if (list != NULL) WlanFreeMemory(list);
if (handle != NULL) WlanCloseHandle(handle, NULL);
return 0;
}上面的我用自己手机开了个热点进行连接,没有任何问题
断开连接
使用WlanDisconnect函数
代码如下
#include <windows.h>
#include <wlanapi.h>
#include <objbase.h>
#include <wtypes.h>
#include <stdio.h>
#include <stdlib.h>
// Need to link with Wlanapi.lib and Ole32.lib
#pragma comment(lib, "wlanapi.lib")
#pragma comment(lib, "ole32.lib")
// 关闭WLAN连接
int main() {
// 打开连接
DWORD useVersion = 0;
HANDLE handle = NULL;
PWLAN_INTERFACE_INFO_LIST list = NULL;
PWLAN_INTERFACE_INFO info;
DWORD result = WlanOpenHandle(2, NULL, &useVersion, &handle);
if (result != ERROR_SUCCESS) {
printf("WlanOpenHandle执行失败: %d", result);
goto exit;
}
// 获取无线LAN接口,我这电脑只有一个无线LAN接口
result = WlanEnumInterfaces(handle, NULL, &list);
if (result != ERROR_SUCCESS) {
printf("WlanEnumInterfaces失败: %d", result);
goto exit;
}
info = &list->InterfaceInfo[0];
/*
WlanDisconnect 断开从其当前网络的接口
参数
HANDLE hClientHandle, 句柄
const GUID *pInterfaceGuid, 接口
PVOID pReserved NULL
返回值
ERROR_INVALID_PARAMETER hClientHandle为NULL或无效,pInterfaceGuid为NULL,或pReserved不为NULL。
ERROR_INVALID_HANDLE 在句柄表中找不到 句柄hClientHandle
RPC_STATUS 各种错误代码
ERROR_NOT_ENOUGH_MEMORY 无法为查询结果分配内存
ERROR_ACCESS_DENIED 呼叫者没有足够的权限
*/
result = WlanDisconnect(handle, &info->InterfaceGuid, NULL);
if (result != ERROR_SUCCESS) {
printf("断开失败: %d", result);
} else {
printf("断开成功");
}
exit:
// 关闭句柄,释放资源
if (list != NULL) WlanFreeMemory(list);
if (handle != NULL) WlanCloseHandle(handle, NULL);
return 0;
}Java代码操作
因为我主要是做Java的,所以使用Java更顺手,所以我将上面的操作封装成dll供JNI调用
提供了五个函数

有了以上的基础,就可以暴力套WLAN密码了
最后,我将写好的JNI以及案例代码放到了github
案例源码地址 https://github.com/1711680493/Application/tree/master/TestWlan
















