1

我找不到如何从命令提示符或 powershell 在 Windows 10 中启动 WPS 客户端。当我使用 Linux 时,使用 wla_supplicant (wpa_cli wps_pbc) 一切都变得非常简单。Windows中有类似的东西吗?

有谁知道如何在 Windows 中设置 Wi-Fi 网络(通过 WPS)密钥而无需人工输入?

我还尝试了 Microsoft 的 WCN(Windows Connect Now),因为它实现了 WPS 功能。我还从 WCN 上的 Windows SDK 获得了示例,但他们无法通过 WPS 获取密钥(失败)。但如果我使用 Windows 用户界面连接 wiothout PIN,一切似乎都很好。

我确信有可能做到这一点,通过从命令提示符或应用程序 (C++/C#) 按钮启动来执行 Wifi 保护设置非常重要,而无需人为入侵或输入(一旦 WPS 播出,Windows 应该自动获取网络密钥,然后连接)。

4

3 回答 3

2

不知道会不会来不及回答,把我知道的放在这里,希望对你有帮助。

首先,如果您的系统已经更新到 16299(Fall Creator Update),您可以简单地使用 UWP 的新 wifi api。安装最新的 Windows SDK,创建一个 C# 控制台项目,目标 C# 版本至少为 7.1,然后添加两个对项目的引用。

  1. C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETCore\v4.5\System.Runtime.WindowsRuntime.dll
  2. C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.16299.0\Windows.winmd

毕竟,下面的代码应该可以工作。

using System;
using System.Threading.Tasks;
using Windows.Devices.Enumeration;
using Windows.Devices.WiFi;

class Program
{
    static async Task Main(string[] args)
    {
        var dic = await DeviceInformation.FindAllAsync(WiFiAdapter.GetDeviceSelector());
        if (dic.Count > 0)
        {
            var adapter = await WiFiAdapter.FromIdAsync(dic[0].Id);
            foreach (var an in adapter.NetworkReport.AvailableNetworks)
            {
                if (an.Ssid == "Ssid which you want to connect to.")
                {
                    // Fouth parameter which is ssid can not be set to null even if we provided
                    // first one, or an exception will be thrown.
                    await adapter.ConnectAsync(an, WiFiReconnectionKind.Manual, null, "",
                        WiFiConnectionMethod.WpsPushButton);
                }
            }
        }
    }
}

构建并运行exe,然后按下路由器的按钮,您的电脑将连接到路由器。

但是如果你不能更新到 16299,WCN 将是你唯一的选择。您可能已经注意到,如果首先使用按钮方法调用 IWCNDevic::Connect,WSC(Wifi 简单配置)会话将失败。这是因为 WNC 不会以登记者的身份启动按钮会话,而只会以注册商的身份启动。这意味着您必须确保在调用 IWCNDevic::Connect 之前已按下路由器的按钮。这样做的方法是使用 Native Wifi api 重复扫描您的路由器,从扫描结果中分析最新的 WSC 信息元素,确认 Selected Registrar 属性已设置为 true 并且 Device Password Id 属性已设置为 4。之后,查询IWCNDevice,调用Connect函数就成功了。然后您可以调用 IWCNDevice::GetNetworkProfile 来获取可用于连接到路由器的配置文件。

  • WlanEnuminterfaces:用于获取可用的 wifi 接口。
  • WlanRegisterNotification:用于注册回调以处理扫描连接结果。
  • WlanScan:用于扫描指定的wifi BSS。
  • WlanGetNetworkBsslist:用于在扫描后获取最新的 BSS 信息。
  • WlanSetProfile:用于保存 BSS 的配置文件。
  • WlanConnect:用于连接到 BSS。

关于 WSC 信息元素及其属性,您可以在Wi-Fi 简单配置技术规范 v2.0.5中找到所有信息。

于 2018-01-25T15:39:46.957 回答
0

@Alex.Wei

可以构建这个解决方案,但它会在执行时抛出异常

static private async Task ConnectWifiAsync(int connection_timeout, string SSID, string BSSID)
    {
        DeviceInformationCollection dic = await DeviceInformation.FindAllAsync(WiFiAdapter.GetDeviceSelector());
        if (dic.Count > 0){
            var adapter = await WiFiAdapter.FromIdAsync(dic[0].Id);
            foreach (var an in adapter.NetworkReport.AvailableNetworks){
                if (an.Ssid == SSID && an.Bssid == BSSID){
                    var ConnectTask = adapter.ConnectAsync(an, WiFiReconnectionKind.Manual, null, "", WiFiConnectionMethod.WpsPushButton);
                    if (await Task.WhenAny((Task)ConnectTask, Task.Delay(connection_timeout)) == ConnectTask){
                        Console.WriteLine("Connection completed within timeout");
}}}}}

在 Task.WhenAny() 行执行错误消息:未处理的异常:System.InvalidCastException:无法将类型为“System.__ComObject”的 COM 对象转换为类类型“System.Threading.Tasks.Task”。表示 COM 组件的类型的实例不能转换为不表示 COM 组件的类型;但是,只要底层 COM 组件支持对接口的 IID 的 QueryInterface 调用,它们就可以转换为接口。在 ConsoleApp2.Program.d__1.MoveNext()

于 2022-01-27T05:37:44.753 回答
0

对于克里斯。关于超时。
你不能直接IAsyncOperation投到Task。正确的方法是使用AsTask方法。而且,您应该ConnectAsync在超时后取消。
示例代码:

var t = adapter.ConnectAsync(an, WiFiReconnectionKind.Manual, null, "",
    WiFiConnectionMethod.WpsPushButton).AsTask();
if (!t.Wait(10000))
    t.AsAsyncOperation().Cancel();
于 2022-01-27T14:26:07.667 回答