简体   繁体   中英

How to reference Windows.winmd from a .NET Core library?

I'm looking to use Windows Runtime types, like Frame or Button , from a .NET Core library. It seemed to be working fine when I was using a traditional PCL, targeted for Windows/Windows Phone 8.1. For some reason, however, it's not compiling after I switched my project to DNX.

Here's my project.json :

{
    "frameworks": {
        // Profile32 == Windows + Windows Phone 8.1
        ".NETPortable,Version=v4.6,Profile=Profile32": { }
    }
}

And here is my sample code:

using System.Linq;
using Windows.UI.Xaml.Controls;

public class Sample
{
    public void Method()
    {
        Enumerable.Empty<Frame>();
    }
}

I was getting a compiler error on Frame in this snippet, saying that the type couldn't be found. So, I did a little detective work on this and hit F12 on it in my regular PCL, to look at its declaring assembly.

It turns out that most of the Windows Runtime types I want live in a single assembly called Windows.winmd , which is found somewhere in Program Files. I'm curious to know, is there any way I can reference this assembly from my .NET Core library?

Thanks!

(Note that I can't just use a regular PCL, since I have needs that are specific to .NET Core.)


meta: By the way, please don't remove the asp.net-core tag from this question, since this is related to DNX.


edit: I've just tried this:

".NETPortable,Version=v4.6,Profile=Profile32": {
    "frameworkAssemblies": {
        "Windows": { "type": "build" }
    }
}

Unfortunately, this doesn't seem to be working either, although the compiler has no problem resolving assemblies like System.Linq or System.Runtime .

The framework moniker (TFM) are a bit confusing.

The Profile 32 targets "Windows 8.1, Windows Phone 8.1" (=platform standard of 1.2).

The lower the standard, the more platforms can consume the class library, but they have the fewest features. The higher the standard, the more features can be used, but the platforms may be limited.

So if you want to support/use a winmd in your "Class Library (package)", you need to use the net (when targeting the full .NET framework) and dotnet (when targeting the .NET core framework) monikers.

From the .NET platform standard link above:

Exising PCL projects in VS2013 and VS2015 (excluding UWP targets), can only target up to .NET Platform Standard version 1.2.

I'm not sure if this also applies to .winmd files. But somethings you could try is to target dotnet51 , dotnet52 or dotnet53 for .NET Core. You can't use .NET 4.6 ( dotnet54 and dotnet55 monikers) and still target Windows 8.1, this will only work for UWP. According to a post of Marc Garvell the versions are off by one (so dotnet51 equals netstandard1.0 and dotnet5.5 equals netstandard1.4 )

It seems that the names of the monikers are for the upcoming ASP.NET Core 1.0 RC2 version and for current RC1 you may still have to apply the dotnet monikers.

Of course you can target multiple frameworks (for each framework defined, one assembly will be compiled), but you'll have to use preprocessor directives to remove your winmd/win8.1 classes from your code and replace it with something that works on the newer platforms.

Remember, that for Class Library (Package) you have to use "net" and "dotnet" moniker, while for .NET Core applications and test projects you still use "dnx" and "dnxcore".

Right now it's a mess, but it should be much better with the next RC2... I hope

Well, looks like I found the answer.

The trick was to base your project off csproj instead of xproj, which you can do by following the steps here .

Once you've done that, just go to your project's properties and retarget the lib to Windows 8.1 and Windows Phone 8.1. Then you'll see the little assembly icon for Windows pop up, like this:

netcoreapp3.0库中添加对Microsoft.Windows.SDK.Contractsnetcoreapp3.0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM