@juanperezADD commented on Mon Sep 03 2018
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:
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
@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:
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.
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:
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