42

Can I use .NET Core with legacy .NET Framework dlls? The answer seems to be no... but I can only find resources referring to project.json, which doesn't exist anymore.

I created a new .NET core library and tried to reference a legacy .NET framework DLL. When I tried to call into the DLL, VS 2017 complained that I didn't have the Stream object is was looking for.

It suggested I reference either mscorlib.dll or install a NuGet package.

The quick help failed to reference mscorlib.dll. If I manually referenced it, I get the following error:

The type 'TargetFrameworkAttribute' exists in both 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' and 'System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' C:\Users...\AppData\Local\Temp.NETCoreApp,Version=v1.1.AssemblyAttributes.cs

The NuGet package is Microsoft.NETFx2.0. The quick help fails to install it. If I run it from the command line:

> PM> install-package microsoft.netfx20   GET
> https://api.nuget.org/v3/registration2-gz/microsoft.netfx20/index.json
> OK
> https://api.nuget.org/v3/registration2-gz/microsoft.netfx20/index.json
> 46ms Restoring packages for ... Install-Package : Package
> Microsoft.NetFX20 1.0.3 is not compatible with netcoreapp1.1
> (.NETCoreApp,Version=v1.1). Package Microsoft.NetFX20 1.0.3 supports:
> net20 (.NETFramework,Version=v2.0)At line:1 char:1
> + install-package microsoft.netfx20
> + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>     + CategoryInfo          : NotSpecified: (:) [Install-Package], Exception
>     + FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand
> Install-Package : One or more packages are incompatible with
> .NETCoreApp,Version=v1.1.At line:1 char:1
> + install-package microsoft.netfx20
> + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>     + CategoryInfo          : NotSpecified: (:) [Install-Package], Exception
>     + FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand
> Install-Package : Package restore failed. Rolling back package changes
> for .At line:1 char:1
> + install-package microsoft.netfx20
> + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>     + CategoryInfo          : NotSpecified: (:) [Install-Package], Exception
>     + FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand
> Time Elapsed: 00:00:00.8035644
Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
Hoppe
  • 6,508
  • 17
  • 60
  • 114

3 Answers3

53

Difficult topic. Generally .NET Framework and .NET Core are incompatible. They target a different set of assemblies (mscorlib vs. System.Runtime) which causes incompatibilities since all usages of types are prefixed with the assembly the type is from.

Starting with .NET Core 2 (currently in preview), you can reference .NET Framework assemblies through an invisible compatibility shim. This allows you to reference the assembly and compile successfully.

It doesn't guarantee though that the application will run successfully, since .NET Core doesn't provide all the APIs from .NET Framework. You'll get PlatformNotSupportedException or MissingTypeException and friends at runtime if that's the case.

Pang
  • 9,564
  • 146
  • 81
  • 122
Suchiman
  • 1,636
  • 2
  • 20
  • 30
  • 2
    So how this 'invisibility' thing connected to .NET Standard? Does what I access in my 'old' DLL need to be in .NET Standard for this 'shim' to work? And with .NET Core 3 they're not breaking this right?! – Simon_Weaver Jan 12 '19 at 05:36
  • 4
    @Simon_Weaver It is not connected to .NET Standard. .NETCoreApp is a superset of .NET Standard and if the .NET Framework APIs you're trying to use exists in .NETCoreApp then the .NET Framework API should work on .NET Core. No, there are no plans right now to drop this feature anytime soon. – Suchiman Jan 12 '19 at 11:19
  • 2
    @Suchiman So if the API do exist in .NET Core, it will be compiled and run under Core runtime or CoreCLR instead? – joe Apr 01 '19 at 05:12
  • 2
    @joe Yeah...No..., You create a .NET Core Project and then you can reference dlls / nuget that were built for .NET Framework (long ago). When you run the .NET Core Project, it will attempt to load and execute the .NET Framework dll which works as long as the API exists in core, if the API does not exists, an error is thrown. CoreCLR is the Core runtime btw. – Suchiman Apr 01 '19 at 11:09
  • @Suchiman I mean if all APIs exist, does it mean that all .NET Framework dlls and .net core libraries should be running under CoreCLR, managed by CoreGC. And they should be able to run under linux. Or .net framework dlls will manage its own Runtime and CLR instead of hosting under CoreCLR? – joe Apr 02 '19 at 08:38
  • 1
    @joe no that's what i've tried to say, there won't ever be the .NET Framework loaded, incompatibility results in errors, not falling back to .NET Framework. – Suchiman Apr 02 '19 at 16:59
15

Building on top of Suchiman's answer, the compatibility shim will allow a .NET Core application to reference .NET Framework libraries and succeed at compile time but the .NET Core application may fail at run time if any required underlying .NET Framework libraries are missing.

To improve the chances of success at run time, you can try using the Windows Compatibility Pack. This basically attempts to fill in missing .NET Framework libraries. The downside is that the Windows Compatibility Pack is somewhat specific to Windows so it may affect the cross-platform compatibility of the .NET Core app.

datchung
  • 3,778
  • 1
  • 28
  • 29
6

I am not sure what the compatibility shim the other answers are referring to is but, as of .NET Core 2, you can directly reference a .NET Framework dll in a .NET Core project.

Note that a .NET Framework dll might be using some Windows specific APIs so you might lose out on the cross-compatibility of .NET Core. But, if you're just looking to upgrade to a newer version of C# (since they are now only available on newer versions of .NET Core and .NET), it won't matter that much. If you're on .NET 5 or newer, you might want to use the Windows TFM net5.0-windows to make sure your project is only built for Windows.

If the .NET Framework dll is using certain Windows APIs that are not available in .NET Core, then you can reference the Microsoft.Windows.Compatibility NuGet package (more info here, and here).

somethingRandom
  • 811
  • 11
  • 16