Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use Wi-Fi Direct from a non Universal application?

I've been trying to code a simple command-line based application (using C# and .NET from Visual Studio 2015 and Windows 10) to start a Wi-Fi Direct advertiser following Microsoft's Universal Samples, but manually adding references to the necessary *.dll and *.winmd assemblies instead of creating a UniversalWindowsPlatform project. (System.Runtime.WindowsRuntime from Refference Assemblies and Windows from Windows Kits\10\Union Metadata\Windows.winmd)

This is the relevant code:

public void StartAdvertisement(WiFiDirectAdvertisementListenStateDiscoverability discoverability,
        bool listenToConnections)
    {
        if (mPublisher == null)
            mPublisher = new WiFiDirectAdvertisementPublisher();

        if (listenToConnections)
        {
            mListener = new WiFiDirectConnectionListener();
            mListener.ConnectionRequested += OnConnectionRequested;
        }

        mPublisher.StatusChanged += OnStatusChanged;
        mPublisher.Advertisement.IsAutonomousGroupOwnerEnabled = true;
        mPublisher.Advertisement.ListenStateDiscoverability = discoverability;
        mPublisher.Start();
    }

async void OnConnectionRequested(WiFiDirectConnectionListener sender,
        WiFiDirectConnectionRequestedEventArgs connectionEventArgs)
    {
    // Connection code
    }

The advertiser starts OK (it can be found from other devices, and it creates the necessary network interface), but the OnConnectionRequested method doesn't get called when other devices attempt to connect. I've seen that for using Wi-Fi Direct, an Universal Windows Application must add to its manifest the proximity capability, but for a generic application, there is no manifest.

Can I use the Windows 10 WiFi Direct API from a non-universal Windows application only by referencing the necessary assemblies?

like image 964
S_Luis Avatar asked Oct 19 '22 03:10

S_Luis


1 Answers

So, I finally could use the WinRT APIs (including the Wi-Fi Direct ones even without a manifest declaring the proximity capability use) from a non-Universal Windows application, but in Windows 10 is a little bit trickier than in 8 or 8.1.

Once you edit the *.csproj of your project to add the following line inside the group...

<TargetPlatformVersion>10.0.10240.0</TargetPlatformVersion>

you'll see a new section inside the Reference Manager called Windows, with winmd libraries. None of them will be useful, all you probably need is inside two libraries that you'll have to add browsing:

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

With those two references you'll avoid problems like

'The type XXXX is defined in an assembly that is not referenced'

or

'The namespace XXXX is defined in two different assemblies'.

But we're not done yet! Particularly in Wi-Fi Direct, once the advertiser is, you know, advertising, and some other computer attempts to connect, if you have an instance of WiFiDirectConnectionListener, the following method should be called

async void OnConnectionRequested(WiFiDirectConnectionListener sender, WiFiDirectConnectionRequestedEventArgs connectionEventArgs)

but instead you get a System.BadImageFormatException. That's because the System.Runtime.WindowsRuntime.dll actual version differs somehow from the one declared in its manifest, so it can't be loaded.

Open the properties tool in Visual Studio, select the System.Runtime.WindowsRuntime reference and change the following properties: Copy Local to false and Specific Version to true.

Now it should work!

like image 161
S_Luis Avatar answered Oct 21 '22 18:10

S_Luis