Sdk: CustomAssemblyLoaderContext throws PlatformNotSupportedException when invoking an assembly that uses the System.Management package

Created on 4 Sep 2018  路  3Comments  路  Source: dotnet/sdk

@juanperezADD commented on Mon Sep 03 2018

CustomAssemblyLoaderContext throws PlatformNotSupportedException when invoking an assembly that uses the System.Management package

We have two projects: an Executable and a Loader.

The Executable is a .NET Core 2.0 application that uses the System.Management package to obtain the operating system information. This project is published with the following settings:

  • Deployment Mode: Framework Dependent.
  • Target Runtime: Portable.

The Loader is a .NET Core 2.0 application that loads the assemblies of the Executable project at runtime.

If we execute the Executable project with dotnet, we obtain the operating system information correctly. However, if we load and invoke the Executable project with the Loader, an exception occurs:

System.Reflection.TargetInvocationException

  HResult=0x80131604

  Message=Exception has been thrown by the target of an invocation.

  Source=System.Private.CoreLib

  StackTrace:

   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)

   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)

   at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)

   at Loader.Program.Main(String[] args) in D:\W\JP\Temp\Loader\Loader\Program.cs:line 15



Inner Exception 1:

PlatformNotSupportedException: System.Management currently is only supported for Windows desktop applications.

To solve this, we have to publish the Executable project for Windows instead of Portable.

Why when the Executable is Portable works with the dotnet command and not with the Loader project?

Code sample:
Loader.zip

Most helpful comment

When you publish as a portable application, there are two different versions of System.Management.dll that get deployed. One is used on non-Windows platforms and throws the exception you are seeing while the other is used on Windows and has the actual implementation. Your custom assembly loader is picking the non-Windows one because it happens to be returned first to you from the file system:

image

There's a lot of logic to replicate in a custom loader in order to handle things like platform-specific dependencies as dotnet myprogram.dll does. Take a look at https://github.com/natemcmaster/DotNetCorePlugins, which you can probably leverage for your scenario.

cc @jeffschwMSFT @natemcmaster

All 3 comments

@nguerrera I don't believe this belongs to us, would you know where this should go?

When you publish as a portable application, there are two different versions of System.Management.dll that get deployed. One is used on non-Windows platforms and throws the exception you are seeing while the other is used on Windows and has the actual implementation. Your custom assembly loader is picking the non-Windows one because it happens to be returned first to you from the file system:

image

There's a lot of logic to replicate in a custom loader in order to handle things like platform-specific dependencies as dotnet myprogram.dll does. Take a look at https://github.com/natemcmaster/DotNetCorePlugins, which you can probably leverage for your scenario.

cc @jeffschwMSFT @natemcmaster

I just ran into this with a .NET Core 3.0 plugin system I'm working on. Two versions of System.Management.dll get deployed in my plugin: one is in the same directory as the plugin assembly and one is in runtimes\win\lib\netcoreapp2.0. I have to delete the sibling copy of System.Management.dll to ensure the runtimes\win\lib\netcoreapp2.0 one gets loaded.

Was this page helpful?
0 / 5 - 0 ratings