1

I can not find how to start WPS client in Windows 10 from command prompt or powershell. When I used Linux, everything was really ease with wla_supplicant (wpa_cli wps_pbc). Is there something similar in Windows?

Does anyone know how to set up Wi-Fi network (over WPS) key without human input in Windows?

I also tried WCN (Windows Connect Now) from Microsoft as it implements WPS features. I got also samples from Windows SDK on WCN, but they could not get key by WPS (it faild). But if I use Windows user interface to connect wiothout PIN, everyting seems to be pretty fine.

I am sure that there is possibility to do that, it is very important to perform Wifi Protected Setup by button start from the command prompt or app (C++/C#) without human intrusion or input (once WPS is on air, Windows should automatically get the network key and connect then).

2 Answers2

2

I don't know if it's too late to answer, just put what I know in here and hope it can help.

First, if your system has updated to 16299(Fall Creator Update), you can just simply use new wifi api from UWP. Install newest Windows SDK, create a C# console project, target C# version to at least 7.1, then add two reference to the project.

  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

After all of that , code in below should work.

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);
                }
            }
        }
    }
}

Build and run the exe, then push your router's button, your pc will be connect to the router.

But if you can not update to 16299, WCN will be your only choice. You may already notice that if call IWCNDevic::Connect frist with push-button method, the WSC(Wifi Simple Configuration) session will fail. That's because WNC would not start a push-button session as a enrollee, but only as a registrar. That means you have to ensure that router's button has been pushed before you call IWCNDevic::Connect. The way to do that is using Native Wifi api to scan your router repeatedly, analyse the newest WSC information element from the scan result, confirm that Selected Registrar attribute has been set to true and Device Password Id attribute has been set to 4. After that, query the IWCNDevice and call Connect function will succeed. Then you can call IWCNDevice::GetNetworkProfile to get a profile that can use to connect to the router. Because it's too much of code, I will only list the main wifi api that will be used.

  • WlanEnuminterfaces: Use to get a available wifi interface.
  • WlanRegisterNotification: Use to register a callback to handle scan an connect results.
  • WlanScan: Use to scan a specified wifi BSS.
  • WlanGetNetworkBsslist: Use to get newest BSS information after scan.
  • WlanSetProfile: Use to save profile for a BSS.
  • WlanConnect: Use to connect to a BSS.

And about the WSC information element and it's attributes, you can find all the information from Wi-Fi Simple Configuration Technical Specification v2.0.5.

Alex.Wei
  • 1,798
  • 6
  • 12
  • Thanks, sounds great! But I don't know what is the SSID... So, the part of this `an.Ssid == "Ssid which you want to connect to."`is really annoying, but it handles my issue! Thanks! – Svyatoslav Krasnitskiy Mar 16 '18 at 14:58
  • Thank you. I have one more question. Would it be possible to extend your sollution with timeout? I tried to extend based on this: https://stackoverflow.com/questions/4238345/asynchronously-wait-for-taskt-to-complete-with-timeout but I could compile, but it failed at execution. – Krisz Jan 26 '22 at 17:16
  • @Krisz It can be done with timeout. And I think you're on the right direction. If you can show your code, I should be able to tell you what's went wrong. – Alex.Wei Jan 27 '22 at 00:36
  • I have added the code in a separate answer. Could you have a look? – Krisz Jan 27 '22 at 09:53
0

For Krisz. About timeout.
You can't cast IAsyncOperation to Task directly. The right way to do that is using AsTask method. And also, you should cancel ConnectAsync after timeout.
Sample code:

var t = adapter.ConnectAsync(an, WiFiReconnectionKind.Manual, null, "",
    WiFiConnectionMethod.WpsPushButton).AsTask();
if (!t.Wait(10000))
    t.AsAsyncOperation().Cancel();
Alex.Wei
  • 1,798
  • 6
  • 12