FileNotFoundException when referencing DLL in .NET Core Application - c#

I have a .NET Core console application and a .NET Core class library. Both are extremely simple, single class projects. Both are freshly built, with a fresh install of the latest .NET Core. Both target .NET Core 1.1.
This error occurs at runtime whenever I include a .NET Core class library in an application:
System.IO.FileNotFoundException: 'Could not load file or assembly
'NAME, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. The
system cannot find the file specified.
Building either projects are fine, and Intellisense shows me the contents of the class library after including a using... statement. With the reference and code written there are no issues at compile time.
I've set the Copy Local to Yes for the referenced assembly in my console application. The referenced DLL exists in the bin folder of the console application during run time.
Here is the csproj reference:
<Reference Include="NAME">
<HintPath>path\bin\Debug\netcoreapp1.1\NAME.dll</HintPath>
<Private>true</Private>
<SpecificVersion>false</SpecificVersion>
</Reference>
This only happens with .NET Core DLLs, I have absolutely no issues with .NET Framework 4.5.* and up.
Could anybody shed some light on this issue? Any SO/MSDN pages I've found regarding this have been specific problems like targeted the incorrect version of a DLL, which doesn't help.

Referencing DLL files in a .NET Core application is not supported using the pre-2.0 tools.
The reason is that the dependency graph (deps.json file) generation does not include these files and most likely wouldn't work anyway since it cannot consolidate references / dependencies of the referenced DLL anyway.
For the upcoming 2.0 release, this scenario should work as long as you also reference all DLLs / packages that the original package is using. The syntax would be:
<Reference Include="path/to/my.dll" />
.NET Core 2.0 will also support referencing assemblies that have been built for .NET 4.6.1 this way, but it may fail at runtime if the DLL uses unsupported API calls.

After lots of digging, I found a solution for .NET Core 2.0 that works for me.
The core issue: I added the project references through Visual Studio 2017. In my web application, I referenced two .NET Core libraries; while everything compiles, at runtime, I get a FileNotFound exception pointing to one of the two DLLs.
The solution that worked for me:
Close Visual Studio
Open the .csproj with the references in it. Delete the references to the projects.
From a terminal, cd into the project folder and add the references by hand, using dotnet add reference ..\..\foo\bar.csproj
Start Visual Studio, build and run your (web) application
For me, this resolved the issue.

Not sure if this would count as a fix but it's a workaround at least.
Rather than referencing the DLL I've simply added the project for the class library to the console application, included a dependency reference to the class library project in the console application and clean/rebuilt. Working fine.
Obviously this isn't a fix for DLLs that are proprietary, but it may help.

Related

NuGet; Transitive Dependencies; Binding Redirect Hell

.NETCore just litters your disk a lot worse, too many versions, too many assemblies, too many standards and no GAC. Hopefully they'll get their act together sometime soon. – Hans Passant Aug 17 '17 at 10:37
No, it just keeps getting worse.   : \
Have a .NET Standard 2.0 class library that references Microsoft extension classes. When we deploy to the server, we get runtime binding exceptions. My questions first:
Why aren't binding redirects being generated for transitive dependencies?
Since they're not, how do I come up with a full list to add manually?
How does the compiler know what version to redirect to unless it intends for me to deploy the version it compiled against?
How do I come up with a list of DLLs to deploy - excluding framework DLLs but including anything that wouldn't be on the server?
Is a nuget package broken if the assembly version in \ref\ is lower than the assembly version in \lib\?
Details:
We have a class library compiling against .NET Standard 2.0... it references Microsoft.Extensions.Configuration.Json.
MimExtension
\--Dependendencies
\--Packages
\--Microsoft.Extensions.Configuration.Json (5.0.0)
\--System.Text.Json (5.0.0)
\--System.Buffers (4.5.1)
System.Buffers resolves to \.nuget\packages\system.buffers\4.5.1\ref\netstandard2.0\System.Buffers.dll. The file version in that directory is 4.6.28619.1, date 2020/02/19. .NET Reflector shows the assembly version as 4.0.2.0.
The \lib\ version of that DLL is \.nuget\packages\system.buffers\4.5.1\lib\netstandard2.0\System.Buffers.dll... same file version and date, but the assembly version is 4.0.3.0.
Compiling the DLL gives me a .dll.config file with binding redirects that I could copy into the consuming application's app.config - but System.Buffers.dll and System.Text.Json.dll aren't there. Microsoft.Extensions.Configuration.Json.dll also isn't there - though another nuget package, Microsoft.Extensions.Configuration.Abstractions.dll, is.
I'm assuming this means the compiler thinks no redirect is necessary for the DLLs that aren't in there (see question #3). It makes sense that only DLLs with conflicts across references get added to the binding redirects (if that's what's happening), but conflict or not, our app won't bind to the \lib\ version of the System.Buffers.dll the compiler uses and RTE's (question #1).
To resolve this I can add binding redirects manually. But how do I look at all the nuget references in my project and determine (recursively) what version was chosen for each dll? Short of dumping verbose build output to a text file with some fancy regex and an hour of copy and paste, that is (question #2).
Note: I can add <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> to the .csproj file and get all referenced dlls dumped to the output directory - including .NET dlls like System.Threading.dll and System.Runtime.CompilerServices.Unsafe.dll- but that still doesn't get me a full list of what versions each one are... especially since I need assembly versions, which I can't even display in explorer.
Regarding that... some of the binding redirects generated automatically are for .NET assemblies like System.Threading... does VS really expect me to deploy the version of System.Threading I compiled against? For that dll, I have newVersion="4.0.11.0"... our server has assembly version 4.0.0.0, file version 4.8.3761.0. VS expects me to deploy assembly version 4.0.11.0, file version 1.0.24212.01 (wtff?!?). The 4.0.11.0 version pulled down by nuget is dated 2019/12/26... the 4.0.0.0 server version is dated 2021/01/21.
I'm guessing that's a Core vs. Framework versioning wtf - but binding redirects don't care. The app that will load our library is .NET Framework 4.8... am I supposed to deploy the System.Threading 4.0.11.0 dll with my app, or manually change the binding redirect and let it load the server's version? It's absolutely ludicrous that a core DLL has a higher assembly version than its newer .NET Framework counterpart (question #addingnewonesasigo).
So when we're referencing nuget packages, how do we know what needs deployed and what doesn't (or worse, shouldn't be)? (question #4) I feel like the build process should copy dlls that aren't part of the framework/won't be in the GAC to the output directory - but there's nothing TIAO to indicate that in the nuget package specs.
Regarding #5... shouldn't the dlls in a nuget package have the same version in the \ref\ and \lib\ folders? The breakdown in Microsoft.Extensions.Configuration.Json is in System.Text.Json... S.T.J's .nuspec lists a .NET Standard 2.0 dependency to <dependency id="System.Buffers" version="4.5.1" />. So why would the System.Buffers.dll nuget cache have different versions in \ref\ and \lib\? Shouldn't they both be either 4.0.2.0 or 4.0.3.0?
There are a lot of questions out there on this - even some specifically to System.Buffers. But nobody has resolved this satisfactorily (that I can find) for a class library. I'm going to try adding a scratch website to the solution and reference the library - just to see whether .NET gets the necessary dlls/redirects in place for its only love: Web
Update
I manually added a binding redirect to 4.0.3.0 for System.Buffers... and immediately got the next mole to whack: Could not load file or assembly 'System.Numerics.Vectors, Version=4.1.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies
And so it will go, until we find a way to list everything that VS probed. And without 100% regression coverage, there's no guarantee we won't miss something when we deploy.
For an executable, dotnet publish; and ship the resulting folder is always correct.
But for a dll compiled against .net standard; I've only had success building a nuget package and referencing it and letting the compiler (whole package thereof) figure out what final dlls the project needs. You can make a nuget package with dotnet pack.
I have never needed binding redirects to link .netstandard to .net framework.
Compiling the library for specific platforms pulls the dependent DLLs into the bin folder. This makes sense in retrospect - compiling for .NET Standard is only meaningful when the target platform isn't known and won't be chosen by the developer of the library. That scenario requires a centralized package manager.
Targeting for .NET 4.8 (highest version currently supported by MIM) gave us the DLLs in the bin directory and set binding redirects in the config file.
That said, the System.Buffers.DLL version issue only went away because the .NET 4.8 dependencies were defined correctly. The Microsoft.Extensions.Configuration.Json .nuspec indicates a different assembly version than the dll that gets downloaded when compiling for .NET Standard 2.0. I don't know if that's an issue with the references when the .NET developers compiled the nuget package or an unavoidable artifact of nuget packaging itself.

Could not load dll from GAC in .NetCore Application

My sample console application (say App1) developed using .Net Core 3.1 and it calls another .NetCore dll (Say Dll1). I have added as reference dll with "Copy Local = Yes". I am using Visual Studio 2019 as Dev environment.
It works fine in direct scenario. Means, when I set "Copy Local = Yes" in App1.
I have registered that .Net Core dll (Dll1) in GAC and set "Copy Local = No" in App1.
Now I could not load .Net Core (Dll1) and it throws below exception.
Unhandled exception. System.IO.FileNotFoundException: Could not load file or assembly 'xxxxx, Version=1.0.0.0, Culture=neutral, PublicKeyToken=66f432805192946d'. The system cannot find the file specified.
File name: 'xxxxx, Version=1.0.0.0, Culture=neutral, PublicKeyToken=66f432805192946d'
at xxxxx.Program.Main(String[] args)
My doubts:
Whether .Net Core supports calling dll from GAC?
Kindly help me to resolve this issue.
Regards,
Hari
Your Question
Does .Net Core load assemblies from the Global Assembly Cache (GAC)?
The Short Answer:
Nope
The Long Answer:
When you use an assembly, with CopyLocal = false set, it means that the Assembly (.dll file) will not be placed into the output directory of whatever you just built.
Here, .Net Core acts differently than .Net Framework:
In .Net Framework
As soon as the missing assembly is used somewhere in your executing code, the runtime environment will try to search for it, find and load it. For .Net Framework, this happens in a very specific way, which includes loading it from the GAC (Global Assembly Cache) when available.
And this is how dotnetcore does:
Those dotnetcore apps are designed to be standalones and easy to handle, and do not want to rely on their environment. You deliver all they need to know along with them. So, those apps won't go searching around for missing dlls, and they will not look into the GAC. This is the normal deployment method, and this is called "self contained deployment"
There is, however, something called the runtime package store, that can help optimizing your deployment, by defining that your .Net Core Application is not "self containing", but is deployed against a defined "framework (= where a set of libraries are defined to be present). This is called "framework dependent deployment"
If you need more Information of Framework-Dependent Deployment of .Net Core Apps
Have a look at this
Is there any GAC equivalent for .NET Core?

TypeLoadException: Could not load type IHttpResponseStreamWriterFactory from assembly

I'm building aspnet core app. I wanted to keep one of my MVC Controllers in Class Library (so outside main project).
In order to do that, I've created new class extending Controller in Class Library project called "DataSync". Then, I referenced it in Startup.cs file of main project:
services.AddMvc().AddApplicationPart(Assembly.Load(new AssemblyName("DataSync")));
Here is the error that I see when I try to open main project in browser:
TypeLoadException: Could not load type 'Microsoft.AspNetCore.Mvc.Internal.IHttpResponseStreamWriterFactory' from assembly 'Microsoft.AspNetCore.Mvc.Core, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.
Where should I look for possible problems? What could go wrong here?
I encountered this when I added a new Nuget package (Microsoft.AspNetCore.Mvc.Versioning) which had a dependency on Microsoft.AspNetCore.Mvc.Core 2.2.0. However, the rest of my application was using a lower version.
To fix, check the nuget gallery page for the library, and inspect the Dependencies. Keep lowering the version of the library until it is compatible.
To fix that, I updated versions of libraries that where used by both projects (main project and class library) and ensured that versions are exactly the same. After that, the problem seem to disappear.
I got the same issue. To fix that, I added this nuget package in my project:
Microsoft.AspNetCore.Mvc.Razor
If your application is on .net core 2.0 then that's an issue because Microsoft.AspNetCore.Mvc.Core 2.1.1 is targeted for .net core 2.1. Try removing all references of this nuget and install the nuget targeted for .net core 2.0.
My problem was also related to version mismatch.
Generally CodeGeneration VS Razor.

'Could not load file or assembly 'netstandard, Version=2.0.0.0, ...'. Reference assemblies should not be loaded for execution

Goal:
From a .NET 4.7 console app, using reflection with Assembly.GetType(), I am trying extract the Type of a netstandard 2.0 class from Assembly X. Then I want to create an instance of this Type with Activator.CreateInstance().
What I am trying to do:
However, this assembly X has a dependency to netstandard 2.0. To be able to get the Type, netstandard dependency has to be loaded into the AppDomain. That's why when the AppDomain is requesting the netstandard assembly through the AssemblyResolve event, I simply load the dll like this :
var netStandardDllPath = #"C:\Users\xxx\.nuget\packages\NETStandard.Library.2.0.0-preview1-25301-01\build\netstandard2.0\ref\netstandard.dll";
return Assembly.LoadFrom(netStandardDllPath);
Which throws:
System.BadImageFormatException: 'Could not load file or assembly
'file:///C:\Users\vincent.lerouvillois.nuget\packages\NETStandard.Library.2.0.0-preview1-25301-01\build\netstandard2.0\ref\netstandard.dll'
or one of its dependencies. Reference assemblies should not be loaded
for execution. They can only be loaded in the Reflection-only loader
context. (Exception from HRESULT: 0x80131058)'
Inner Exception: BadImageFormatException: Cannot load a reference
assembly for execution.
What I know:
I know that they want us to load the DLL with Assembly.ReflectionOnlyLoadFrom. But doing that will prevent me from instanciate the type with Activator.CreateInstance(). See Microsoft official post
Also, I tried referencing the Nuget packages NETStandard.Library 2.0.0-preview1-25301-01 and NETStandard.Library.NETFramework 2.0.0-preview1-25305-02 in my console app so it would have the netstandard 2.0 libraries referenced, but it didn't change anything.
Question:
Does anyone would know if there is a proper way to load that dll without error, or maybe if this is a bug, or else? Or why this kind of dll is not able to load for execution?
The netstandard.dll you are trying to load is a reference assembly that which cannot be loaded for runtime on .NET Framework as pointed out by others. However if you need to resolve that dependency you will need to runtime version that maps to the framework you are trying to run on.
For .NET Standard support we are including them as part of the msbuild extensions that ship with VS so you will want to get the version of netstandard.dll from there. Depending on which version of VS2017 you have installed it should be somewhere like C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\netstandard.dll or from the .NET Core 2.0 SDK you can find it C:\Program Files\dotnet\sdk\2.0.0\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\netstandard.dll
Try using one of those versions in your scenario.
Wow. I just spent several hours tracking the cause of this "could not load ... netstandard" error down.
For me, the problem was that my .NET Framework project (which references both .NET Framework and .NET Standard libraries) was built with .NET Framework 4.7.2 and the system where I was deploying and running it did not have 4.7.2 installed.
Deploying a very small Console project with the same basic structure and references and executing that in a Command window finally revealed the correct error, in a pop-up, that .NET Framework 4.7.2 was missing.
If you're struggling with this particular error, make sure you have the necessary .NET Framework installed.
Set Copy Local to true in netstandard.dll properties.
Open Solution Explorer and right click on netstandard.dll.
Set Copy Local to true.
You can't load a reference assembly.
.NET Standard is a collection of APIs that must be provided by .NET Standard compatible implementations.
A reference assembly only contains contracts. This means that it contains no implementation. The assembly you are trying to load contains the .NET Standard 2.0 contracts.
A contract looks like this: https://github.com/dotnet/standard/blob/master/netstandard/ref/mscorlib.cs
EDIT: .NET Framework 4.7 implements .NET Standard 2.0, so you shouldn't need to load any assembly to use Activator.CreateInstance() to instantiate a .NET Standard type.
NETStandard 2.0.0-preview1 in not compatibility with net461 and net47.
but for realese .NET Core SDK 2.0 assemblies (as well as 2.0.0-preview2)
var netStandardDllPath = #"c:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\netstandard.dll";
Console.WriteLine(Assembly.LoadFrom(netStandardDllPath).FullName);
all is ok.
But if you steel need to load preview1 libraries, maybe you should to use netstandard2.0 instead net471.
For me solved doing the following:
1 - Installed latest .Net Framework on server.
2 - Updated windows server and my local machine.
3 - Went to Manage Nuget Package and updated all references on the update tab.
Perhaps only doing step 3 can solve in your case
In case if IBM Message Queue references are used in the project solution, this exception indicates that the DLL used for refering MQ classes are incompatible with the host(server) .NET version installed.
In this scenario, either we need to update server with latest update and make sure .NET latest version is available or use lower version of IBM Message queue DLL as reference.
Old version DLL - amqmdnet.dll (no new features will be introduced by IBM as not in support)
Latest version DLL - amqmdnetstd.dll (to run IBM MQ classes for .NET Standard, you must install Microsoft .NET Core)
Install NetStandard.Library 2.0.0.0 from NuGet , It works for me. when I downgrade .net framework 4.6.1 to 4.6.0
If you are having this issue for a project that used to work, try deleting the bin and obj folders since caching can cause this, too.

Could not load type 'Owin.Extensions' from assembly 'Nancy.Owin, Version=0.23.2.0, Culture=neutral, PublicKeyToken=null'

I did a big round of NuGet updates for my .NET 4.5 Nancy/Owin app. Now I'm getting the above error message and I'm stumped.
I definitely have a reference to Owin.Extensions present, and it's there in the executable directory as well.
I have a parallel set of projects doing this under MONO and it continues to operate smoothly, even after the NuGet updates.
Thought: I can't be sure, but maybe it has something to do with bootstrapping? I was seeing some bootstrapping errors (again only on VS not MONO - Nancy.Bootstrapper.NancyBootstrapperLocator.Bootstrapper related) until I added Nancy.Owin reference to EXE, even though Nancy.Owin reference was present in a dependent DLL.
Please help! Thank you
Problem was the EXE was using .NET 4.5.1 but the DLLs were .NET 4.5
I saw no specific 4.5.1 DLL's actually being referenced, but there must be one lurking about in there somewhere because changing EXE to .NET 4.5 and cleaning up packages.config fixed this issue.

Categories