如何强制 Windows 从命令行重新扫描可用的无线网络?
(即,我正在寻找与在 GUI 上按 F5 等效的命令行。)
答案1
我编写了一个小WlanScan.exe
程序(~2 KiB)来做到这一点。
这是 base64 (32 位版本):
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
您可以像这样从 PowerShell 将其保存到文件中(首先将 Base64 保存到WlanScan.txt
):
Set-Content -Path "WlanScan.exe" $([Convert]::FromBase64String($(Get-Content -Path "WlanScan.txt"))) -Encoding Byte
以下是源代码:
#include <tchar.h>
#include <Windows.h>
#ifndef __CRT_STRINGIZE
#define __CRT_STRINGIZE(Value) #Value
#endif
#ifndef _CRT_STRINGIZE
#define _CRT_STRINGIZE(Value) __CRT_STRINGIZE(Value)
#endif
enum { WLAN_NOTIFICATION_SOURCE_ACM = 0x00000008 };
typedef enum _WLAN_NOTIFICATION_ACM { wlan_notification_acm_start, wlan_notification_acm_autoconf_enabled, wlan_notification_acm_autoconf_disabled, wlan_notification_acm_background_scan_enabled, wlan_notification_acm_background_scan_disabled, wlan_notification_acm_bss_type_change, wlan_notification_acm_power_setting_change, wlan_notification_acm_scan_complete, wlan_notification_acm_scan_fail, wlan_notification_acm_connection_start, wlan_notification_acm_connection_complete, wlan_notification_acm_connection_attempt_fail, wlan_notification_acm_filter_list_change, wlan_notification_acm_interface_arrival, wlan_notification_acm_interface_removal, wlan_notification_acm_profile_change, wlan_notification_acm_profile_name_change, wlan_notification_acm_profiles_exhausted, wlan_notification_acm_network_not_available, wlan_notification_acm_network_available, wlan_notification_acm_disconnecting, wlan_notification_acm_disconnected, wlan_notification_acm_adhoc_network_state_change, wlan_notification_acm_profile_unblocked, wlan_notification_acm_screen_power_change, wlan_notification_acm_profile_blocked, wlan_notification_acm_scan_list_refresh, wlan_notification_acm_end } WLAN_NOTIFICATION_ACM, *PWLAN_NOTIFICATION_ACM;
typedef enum _WLAN_INTERFACE_STATE { wlan_interface_state_not_ready, wlan_interface_state_connected, wlan_interface_state_ad_hoc_network_formed, wlan_interface_state_disconnecting, wlan_interface_state_disconnected, wlan_interface_state_associating, wlan_interface_state_discovering, wlan_interface_state_authenticating } WLAN_INTERFACE_STATE, *PWLAN_INTERFACE_STATE;
typedef struct _WLAN_INTERFACE_INFO { GUID InterfaceGuid; WCHAR strInterfaceDescription[256]; WLAN_INTERFACE_STATE isState; } WLAN_INTERFACE_INFO;
typedef struct _WLAN_INTERFACE_INFO_LIST { DWORD dwNumberOfItems; DWORD dwIndex; WLAN_INTERFACE_INFO InterfaceInfo[1]; } WLAN_INTERFACE_INFO_LIST;
typedef struct _WLAN_NOTIFICATION_DATA { DWORD NotificationSource; DWORD NotificationCode; GUID InterfaceGuid; DWORD dwDataSize; void *pData; } WLAN_NOTIFICATION_DATA, *PWLAN_NOTIFICATION_DATA;
typedef void WINAPI WLAN_NOTIFICATION_CALLBACK(WLAN_NOTIFICATION_DATA *, void *);
typedef struct wlan_scan_finished_context { WLAN_INTERFACE_INFO_LIST *interface_list; HANDLE semaphore; } wlan_scan_finished_context;
static void WINAPI wlan_notification_callback(WLAN_NOTIFICATION_DATA *data, void *context)
{
if ((data->NotificationSource | WLAN_NOTIFICATION_SOURCE_ACM) == WLAN_NOTIFICATION_SOURCE_ACM)
{
if (data->NotificationCode == wlan_notification_acm_power_setting_change || data->NotificationCode == wlan_notification_acm_scan_complete)
{
wlan_scan_finished_context *const ctx = (wlan_scan_finished_context *)context;
if (ctx)
{
for (unsigned int i = 0; i != (ctx->interface_list ? ctx->interface_list->dwNumberOfItems : 0); ++i)
{
if (memcmp(&ctx->interface_list->InterfaceInfo[i].InterfaceGuid, &data->InterfaceGuid, sizeof(data->InterfaceGuid)) == 0)
{
ctx->interface_list->InterfaceInfo[i].isState = (WLAN_INTERFACE_STATE)(ctx->interface_list->InterfaceInfo[i].isState | (data->NotificationCode << 16));
}
}
if (ctx->semaphore) { long prev; ReleaseSemaphore(ctx->semaphore, 1, &prev); }
}
}
}
}
int _tmain(int argc, TCHAR *argv[])
{
(void)argv;
unsigned int result;
if (argc > 1) { result = ERROR_INVALID_PARAMETER; }
else
{
HMODULE const wlanapi = LoadLibrary(TEXT("wlanapi.dll"));
if (wlanapi)
{
#define X(Module, Return, Name, Params) typedef Return Name##_t Params; Name##_t *Name = (Name##_t *)GetProcAddress(Module, __CRT_STRINGIZE(Name));
X(wlanapi, DWORD WINAPI, WlanCloseHandle, (HANDLE hClientHandle, void *pReserved));
X(wlanapi, DWORD WINAPI, WlanEnumInterfaces, (HANDLE hClientHandle, void *pReserved, struct _WLAN_INTERFACE_INFO_LIST **ppInterfaceList));
X(wlanapi, void WINAPI, WlanFreeMemory, (void *pMemory));
X(wlanapi, DWORD WINAPI, WlanOpenHandle, (DWORD dwClientVersion, void *pReserved, DWORD *pdwNegotiatedVersion, HANDLE *phClientHandle));
X(wlanapi, DWORD WINAPI, WlanRegisterNotification, (HANDLE hClientHandle, DWORD dwNotifSource, BOOL bIgnoreDuplicate, WLAN_NOTIFICATION_CALLBACK funcCallback, void *pCallbackContext, void *pReserved, DWORD *pdwPrevNotifSource));
X(wlanapi, DWORD WINAPI, WlanScan, (HANDLE hClientHandle, const GUID *pInterfaceGuid, const struct _DOT11_SSID *pDot11Ssid, const struct _WLAN_RAW_DATA *pIeData, void *pReserved));
#undef X
DWORD version;
HANDLE handle = NULL;
result = WlanOpenHandle ? WlanOpenHandle(1, NULL, &version, &handle) : ERROR_PROC_NOT_FOUND;
if (result == ERROR_SUCCESS)
{
WLAN_INTERFACE_INFO_LIST *interface_list = NULL;
result = WlanEnumInterfaces ? WlanEnumInterfaces(handle, NULL, &interface_list) : ERROR_PROC_NOT_FOUND;
if (result == ERROR_SUCCESS)
{
wlan_scan_finished_context context = { interface_list, CreateSemaphore(NULL, 0, (LONG)interface_list->dwNumberOfItems, NULL) };
DWORD prev;
unsigned int nwait = 0;
unsigned long const register_notification_result = WlanRegisterNotification ? WlanRegisterNotification(handle, WLAN_NOTIFICATION_SOURCE_ACM, FALSE, wlan_notification_callback, &context, NULL, &prev) : ERROR_PROC_NOT_FOUND;
for (unsigned int i = 0; i != interface_list->dwNumberOfItems; ++i)
{
unsigned int const result_i = WlanScan ? WlanScan(handle, &interface_list->InterfaceInfo[i].InterfaceGuid, NULL, NULL, NULL) : ERROR_PROC_NOT_FOUND;
interface_list->InterfaceInfo[i].isState = (WLAN_INTERFACE_STATE)(interface_list->InterfaceInfo[i].isState & 0xFFFF);
if (result_i == ERROR_SUCCESS) { ++nwait; }
else { interface_list->InterfaceInfo[i].isState = (WLAN_INTERFACE_STATE)(interface_list->InterfaceInfo[i].isState | (result_i << 16)); }
}
while (nwait > 0)
{
WaitForSingleObject(context.semaphore, INFINITE);
--nwait;
}
for (unsigned int i = 0; i != interface_list->dwNumberOfItems; ++i)
{
unsigned int const result_i = interface_list->InterfaceInfo[i].isState >> 16;
if (register_notification_result == ERROR_SUCCESS && result_i != ERROR_SUCCESS)
{ result = result_i; }
}
if (result == ERROR_SUCCESS && register_notification_result != ERROR_SUCCESS) { result = ERROR_IO_PENDING; }
if (context.semaphore) { CloseHandle(context.semaphore); }
WlanFreeMemory ? WlanFreeMemory(interface_list) : ERROR_PROC_NOT_FOUND;
}
WlanCloseHandle ? WlanCloseHandle(handle, NULL) : ERROR_PROC_NOT_FOUND;
}
}
else { result = (unsigned int)GetLastError(); }
}
return (int)result;
}
答案2
我一直在寻找同样的东西,不幸的是,我似乎无法在 netsh 实用程序中找到任何可以执行此操作的内容。我能想到的最佳解决方案是通过 netsh 命令禁用然后重新启用该接口。启用接口后会有短暂的延迟(1-2 秒),在此期间不会列出任何网络,但这应该不难解决。
我正在使用以下命令:
netsh interface set interface name="<NIC name>" admin=disabled
netsh interface set interface name="<NIC name>" admin=enabled
netsh wlan show networks
编辑:那么如何获取
"<NIC name>"
,即网络接口卡名称。
首先使用命令netsh wlan show networks
如果启用了 WLAN,您将收到如下消息
C:\Users\user1>netsh wlan show networks
Interface name : WiFi
There are 2 networks currently visible.
SSID 1 : Cross
Network type : Infrastructure
Authentication : WPA2-Personal
Encryption : CCMP
SSID 2 : WLAN-0A8E41
Network type : Infrastructure
Authentication : WPA2-Personal
Encryption : CCMP
所以你看,在这种情况下,接口名称现在WiFi
,你可以按照上面的说明进行操作,例如禁用 wlan 卡:
netsh interface set interface name="WiFi" admin=disabled
等等。 :)
答案3
我知道我有点迟了,但另一种方法是重新启动 wlansvc 服务。
Get-Service wlansvc | Restart-Service
不幸的是,这只能通过提升的提示来完成。
答案4
我目前正在运行 Windows 10 家庭版 20H2,并且我可以使用以下命令从任务栏打开可用网络列表来强制重新扫描:
explorer.exe ms-availablenetworks:
我有一个连接到特定网络的批处理;但有时需要重新扫描才能使该网络显示为可用网络。过去当需要重新扫描时,我的批处理将无法连接到网络。我可以手动打开可用网络列表,然后成功执行批处理。
现在,使用上述命令后,我的批处理将打开可用网络列表,从而在尝试连接之前强制重新扫描。我还没有进行过广泛的测试。我猜想在打开列表之后但在尝试连接之前可能需要等待。
我发现这个命令这里。