.net.net-core.net-standard

System.PlatformNotSupportedException: 'Windows Principal functionality is not supported on this platform.'


We are invoking a dotnet standard dll that calls GetCurrent on WindowsIdentity. It works fine in a dotnet core application, but as soon as you import it into a dotnet framework (4.7.2) application is gives this error:

System.PlatformNotSupportedException: 'Windows Principal functionality is not supported on this platform.'

This issue persists, despite having been raised on the dotnet/standard github issues forum a few months ago: https://github.com/dotnet/standard/issues/1279


Solution

  • This sounds like a problem with the way assembly resolution works between build-time vs run-time (which works via a "bait and switch" approach). When you get this kind of problem with transitive dependencies, the first thing to try is to have your library join the bait and switch party, by declaring that it may have different needs on different TFMs. This is pretty easy, fortunately; it often just means changing:

    <TargetFramework>netstandard2.0</TargetFramework>
    

    to

    <TargetFrameworks>netstandard2.0;net472</TargetFrameworks>
    

    This is now a multi-targeting package. When an application (exe, etc) is built (not a library - only applications), it checks the entire dependency tree and figures out what the most appropriate version of the dll is for each package separately. This means that if the application is targeting net472, net48, etc - they'll get your net472 build, which probably has subtly different onward chains itself (even if you can't see them). If the application is targeting .NET Core, they'll get the netstandard2.0 version of your package, and whatever dependencies that has.

    Note: for best coverage, you might want to drop the TFM a bit to:

    <TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
    

    The reason for this is that net461, net462 etc claim to be able to handle netstandard2.0 - so if an application is targeting net461 and your package targets netstandard2.0;net472, then the "best" match is netstandard2.0, which presumably still won't work. You can have as many as you need, of course (and even change the onward references for each) - perhaps:

    <TargetFrameworks>netstandard2.0;netcoreapp3.0;net461;net472</TargetFrameworks>
    

    Usually you only add TFMs to either: