I'm using a tool I wrote that makes a call to the following line in order to inspect a few things, including the assembly version:
var assm = System.Reflection.Assembly.LoadFrom(path);
The tool works as designed, except when I attempt to run it against a .NET Core application.
When I provide a path to an app compiled for .NET Core 3.1, 5.0 or 6.0 I get a System.BadImageFormatException when attempting to load the assembly.
My tool was written in C# using the .NET 4.7.2 Framework and I updated it to use 4.8, but still get the exception. Thinking it might be a mix-up between regular .NET and .NET Core, I wrote the following quick project and compiled it using the same framework as the target app (.NET Core) but I get the very same error.
Turns out, it throws the exception for any and all .NET Core applications. It works OK on typical Windows apps using .NET 4.7.2 Framework etc., but dies on any .NET Core app.
In researching this, I have yet to find anything that suggests .NET Core application manifests are so different that they'll cause this call to choke. All of my apps and testing are compiled as 64bit apps; there's no mix of 64 bit and 32 bit going on.
Steps to reproduce using simple tester app (below):
- Open your flavor of Visual Studio
- Create a new console application project
- In the template fields, enter: C#, Windows and Console respectively
- Select 'Console App' (not: Console App (.NET framework))
- Click Next
- Give your app a short name and click next
- Choose .NET core 5 (or 3.1 or 6 - but you'll need to remove the main{} for 6.0)
- Paste the code below and compile.
- Provide the path to THIS app (or any other .Net core app)
- Scratch head
SIMPLE TESTER:
internal class Program
{
static void Main(string[] args)
{
Console.Write("\r\nEnter complete path to assembly:");
var path = Console.ReadLine();
if (!string.IsNullOrEmpty(path))
{
var assm = System.Reflection.Assembly.LoadFrom(path);
if (assm != null)
{
var c = assm.GetCustomAttributes(false);
if (null != c && c.Length > 0)
{
Console.WriteLine($"Len:{c.Length} Value type:{c}");
Console.WriteLine($"c0:[{c[0]}]");
var x = 1; // convenient breakpoint to examine vars
}
}
}
Console.WriteLine("Complete...");
Console.ReadLine();
}
}
UPDATE:
For anyone reading this now or later, Microsoft has provided a new package for reading cross-architecture .NET assembly attributes: System.Reflection.MetadataLoadContext - available on Nuget.org