C# CLR Excecption "BadImageFormatException: Could not load file or assembly" - dll

I am using VS 2019 Version 16.8.2
I referred a "CLR Class Library(.NET Core)" project in my "WPF App (.NET)" project and i met a exception:
BadImageFormatException: Could not load file or assembly 'LibCLR, Version=1.0.7646.21580, Culture=neutral, PublicKeyToken=null'. An attempt was made to load a program with an incorrect format.
Let me first talk about how I did it.
Create a "WPF App (.NET)" project "TestCLR"
Add a new "CLR Class Library(.NET Core)" project "LibCLR" in this solution
The "common language runtime support" setting of "LibCLR"
Target "TestCLR" to ".NET 5.0"
"LibCLR.h" created automatically in project "LibCLR" and codes was inside
#pragma once
using namespace System;
namespace LibCLR {
public ref class Class1
{
// TODO: Add your methods for this class here.
};
}
Add "new LibCLR.Class1();" in MainWindow.xaml.cs in project "TestCLR"
using System.Windows;
namespace TestCLR {
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
new LibCLR.Class1();
}
}
}
Rebuild All and debug, then i met exception
Then i change the solution platform to x64 or x84, the exception were the same.
It works well if i choice "WPF App (.NET Framework)" for "TestCLR" in step 1 and "CLR Class Library(.NET Framework)" for "LibCLR" in step 2
Why did not it work?
Can not i use a "CLR Class Library(.NET)" project as a project reference in a "WPF App (.NET Core)" project?
How can i solve this problem?

You should change Platform target to "X86" here

The most common answer is changing between x86 and x64 targets. In a comment to your original question, here, you mentioned that you tried that and it didn't work for you. So, I have a suggestion. You are building a WPF project, and targeting dotnet 5.0. Dotnet 5.0 is OS-agnostic. WPF is OS-specific. It needs Windows.
Try using an OS-specific Target Framework Moniker. Open the .csproj file of both projects. Try setting both projects to <TargetFramework>net5.0-windows</TargetFramework>
Clean solution, rebuild, and test.
We've got a solution here that is dependent on Windows. We shouldn't have to, but let's try explicitly targeting it. Especially that C++ project.
More reading
NET 5: Merging .NET Core and .NET Standard with New Target Framework Monikers (TFMs)
New templates Targeting .NET 5.0
Cannot compile WPF applications targeting .NET 5

Related

How can I get ApplicationPartAttribute within .net5 class library?

The task is not practical, it's just learning experiment.
I have .net5 app (which essentially is asp .net core app) which references onto neighboring project "WebControllers" which contains only Controller class.
WebControllers is .net5 class library into which I added reference to Microsoft.AspNetCore.Mvc.Core package. This package allows to create of working Controller object which is discovered by asp .net core infrastructure and which properly handles http requests.
Now I want inside my WebController objec create variable of ApplicationPartAttribute type. I tried doing this like that:
var aaa = new Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartAttribute("asd");
But Visual studio says to me that it don't know ApplicationPartAttribute class and it doesn't offer to use some namespace or add some package.
Let's go to the MSDN. MSDN about this type for .NET5 says:
Namespace: Microsoft.AspNetCore.Mvc.ApplicationParts
Assembly: Microsoft.AspNetCore.Mvc.Core.dll
Package: Microsoft.AspNetCore.App.Ref v5.0.0
Okay, let's try to install this package. Next errors are occured:
NU1213 The package Microsoft.AspNetCore.App.Ref 5.0.0 has a package
type DotnetPlatform that is incompatible with this project.
Package 'Microsoft.AspNetCore.App.Ref 5.0.0' has a package type
'DotnetPlatform' that is not supported by project 'WebControllers'
Why these errors are occured is unclear to me because both projects are .net5 projects and Microsoft.AspNetCore.App.Ref v5.0.0 is designed for .NET 5.
The question is: how can I use ApplicationPartAttribute in .net5 class library?
Add this code in your xxx.csproj file
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App"/>
</ItemGroup>

Issue with nested DLL referencing in a self-contained .Net Core web app running as a Windows service

The Error
First off, lets start with the error message:
System.BadImageFormatException: 'Could not load file or assembly 'System.Management, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. Reference assemblies should not be loaded for execution. They can only be loaded in the Reflection-only loader context. (0x80131058)'
In my experience, this type of error usually occurs if the DLL is missing, or it's not in the expected format/version. However, I cannot work out what I need to do to resolve this error.
The Setup
The main project is an ASP.Net Core 3.1 application.
It is configured to be able to run as a Window service and support Web API and MVC frameworks. So my Program.cs looks something like this:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args)
{
var builder = Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
builder.UseWindowsService();
return builder;
}
}
That part all works great, I can run the app as a Windows service and serve razor views and web API endpoints, etc.
However, there are more projects in this solution. I have a couple of .Net 4.6 class libraries projects that are referenced by the service app. So my solution looks something like this:
Service App (NET CORE 3.1)
Lib 1 (NET 4.6)
Lib 2 (NET 4.6)
Service App references Lib 1, and Lib 1 references Lib 2.
Any code is either of these two libraries works fine and can be used by the service app.
The problem is that Lib 2 references System.Management DLL, and this is what is causing the error. Whenever I use a function that uses that DLL, I get the error above.
The Attempts So Far
My attempts so far have including:
Setting the DLL to "copy to output"
Adding the DLL reference directly to the web service app
Manually copying the DLL to the output folder. Both debug, and publish folder (note: publish is set to "self contained" application)
The Question
Basically, how can I resolve this issue? Or at least, how can I further debug the problem to potentially find a solution.
I can't repro this at the time, but I suspect this to be a bug in the way that the self-contained publication process using dotnet publish resolves transitive dependencies.
The point is, your .NET Core 3.1 application doesn't run on .NET Framework, while the library you reference, call it "Lib 2", does.
And your Lib 2 has a reference to the NuGet package System.Management, which, when installed on a project targeting .NET Framework ... does nothing, except making your project reference the .NET Framework reference assembly for System.Management, found in C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1. At runtime, the .NET Framework will load the appropriate assembly from the GAC, but the .NET Core runtime does not do this.
Now when publishing your .NET Core app, MSBuild walks through the dependencies to be copied, and (again, I suppose) looks at the reference assembly and goes "I want that one!" and copies it to your output directory.
But you can't run reference assemblies, you can just reference them, so at runtime, your application blows up with an exception stating exactly that:
Reference assemblies should not be loaded for execution
A workaround, but definitely not a solution, is to reference the same System.Management package from your .NET Core application, where the package will actually extract a DLL containing runnable code, and that one will be copied to your output directory. But this might cause other issues, such as the DLL being overwritten during build with the reference one.
I'd suggest looking at GitHub whether this is a known issue, or that this is something caused by your project setup.

The type name 'ConfigurationManager' could not be found in the namespace 'System.Configuration'. This type has been forwarded

I received this error in a .NET 5.0 project using Visual Studio 2019 (tried on Community/Student edition as well as Professional).
"The type name 'ConfigurationManager' could not be found in the namespace 'System.Configuration'. This type has been forwarded..."
Many of the answers I found said that you needed to add "using System.Configuration;" as well as add the assembly namespace as a reference through Project -> Add Reference. This answer did not work for me as there is no "References" folder or any option to "Add Reference" in the Project tab. There is also no "Assemblies" tab in the Reference Manager. Only "Projects," "Shared Projects," "COM," and "Browse."
How do I add System.Configuration as a reference so that I may use ConfigurationManager?
Edit: Although this answer may get rid of the error, this is not the "correct" answer as .NET 5 does not support ConfigurationManager. The other answers explain it best.
In Visual Studio 2019, click the Tools tab at the top.
Tools -> NuGet Package Manager -> Manage NuGet Packages for Solution...
Search "System.Configuration.ConfigurationManager".
Install that to your project and the error should be gone.
System.Configuration.ConfigurationManager is not supported in .NET 5. See here for how you would migrate an app with a web.config file to the .NET Core pattern Migration Configuration
While it might be possible to use System.Configuration.Configuration manager in a .NET 5 application, it is a bad idea. The framework has integrated the new stuff with application startup and if you don't use it you are making yourself more work. The newer configuration patterns are easier to use and deploy into multiple environments. If you have an existing .NET classic app you want to port to .NET 5, follow that documentation from above. If this is a new application check out the Microsoft.Extensions.Configuration namespace.
.NEt 5 dosent Use Old ConfigurationManager you need to read from json
public IConfiguration Configuration { get; set; }
public Startup(IHostingEnvironment environment)
{
Configuration = new Configuration()
.AddJsonFile("config.json");
}
var options = ConfigurationBinder.Bind<AppSettings>(Configuration);
Console.WriteLine(options.SomeSetting);
For more info please refer
GitHub.com/aspnet/Options/test/Microsoft.Extensions.Options.Test/OptionsTest.cs

Referencing DLL's between solutions

I've found an interesting issue with using DLL's in .NET Core (.NET Framework works fine). MVCE as follows:
Create an F# (language is irrelevant) .NET Core class library with the following single file (specific code irrelevant as well):
namespace FSharpClassLibrary
module Say =
let hello name =
printfn "Hello %s" name
Create a C# .NET Core class library in a separate solution (very important--it completely works if they are all in the same solution) with the following code:
namespace CSharpClassLibrary
{
public class HelloClass
{
public void Hello(string name)
{
FSharpClassLibrary.Say.hello(name);
}
}
}
Also, add a folder dlls, copy/paste FSharpClassLibrary.dll into it, and add it as a reference to the project (otherwise, the file above won't compile). It's actually not important to move the .dll into the project, but since I'm distributing this second project independently of the first, I need to guarantee the DLL is available.
Finally, add a console app to the same solution as CSharpClassLibrary with the following file:
using System;
using CSharpClassLibrary;
namespace ConsoleApp1
{
public class Main1
{
public static void Main()
{
new HelloClass().Hello("test");
#if DEBUG
Console.Write("Press any key");
Console.ReadKey();
#endif
}
}
}
Finally, go into NuGet and add FSharp.Core version 4.3.4 to both C# projects (just to make sure everything has access to the F# language stuff; not necessary if you create the first class library with C#). Also, I am using VS 15.6; this may or may not be relevant as well.
Set the console app as the startup project and run it. You will get the following error:
System.IO.FileNotFoundException: Could not load file or assembly 'FSharpClassLibrary, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.
File name: 'FSharpClassLibrary, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
at ClassLibrary1.Facade.Hello1.Hello(String name)
at ConsoleApp1.Main1.Main() in C:\Users\***\source\ConsoleApp1\ConsoleApp1\Main.cs:line 11
The most curious part about this is that if I bypass the CSharpClassLibrary library and host FSharpClassLibrary.dll and HelloClass.cs in the ConsoleApp1 project, everything works as expected. The same issue happens if I use two C# DLL's, I used F# because that's what I was working with already.
What I already tried:
Cleaning and rebuilding all projects, making sure each project was referencing the latest build.
Referencing the child (FSharpClassLibrary.dll) from ConsoleApp1 as well as CSharpClassLibrary.dll.
Using the .dll from the obj folder instead of the bin folder (shouldn't matter as far as I'm aware).
Verify that FSharpClassLibrary.dll exists in ConsoleApp1's bin folder.
Double-check that all projects compile to .NET Core, no .NET Standard projects.

How to Make ASP.Net 5 Reference Normal .Net Class Library that is not in your solution

Earlier I asked this question and got an answer that worked. In order to make your ASP.Net 5 application be able to reference a normal .Net class library that targets the .Net Framework 4.5, you must remove the ' "dnxcore50": { }' reference from your project.json file.
Great. That worked with a simple ClassLibrary project which did nothing.
Now I am trying to do it with more complicated class libraries. Class libraries which reference other NuGet Packages for instance (such as HtmlAgilityPack) and the same technique is not working.
This is very frustrating. I am a little dumbfounded that simply referencing a class library no longer works in the new version of ASP.Net.
One of the "features" that seems to be removed is the ability to reference a compiled DLL for a project that is not in your solution. The "Browse" button is gone from the Add Reference dialog in an ASP.Net 5 project:
Whereas a classic project still has the browse button:
Why? How do I reference a class library that is on my machine, yet I do not want to include in my project?
To reference a DLL on your machine but not in your Solution, you'll need to update the project.json as follows:
{
"frameworks" :
{
"dnx451" :
{
"bin" : { "assembly": "<path to dll>", "pdb": "<path to pdb if needed>" }
}
}
}
Unfortunately, much of the dnx tooling is not yet integrated into VS2015 (the teams are separate, and both are changing too quickly to keep up with each other particularly well), and the Asp.net documentation is still a work in progress.