How do I help my console application find all the referenced assemblies? - c#

tl;dr: My .NET Core 3.1 console application crashes with a FileNotFoundException because a (referenced?) assembly is present in version A, but required in version B. What to do?
I am trying to get a console application to run that is now built for .NET Core 3.1, but that used to be a .NET Framework 4.8 project before it was converted.
The console application crashes with a System.IO.FileNotFoundException, saying that the assembly Microsoft.Extensions.FileProviders.Physical in version 3.1.0.0 cannot befound. Now, I can confirm it's not there - in the directory where the .exe file of my console application resides, there is a file named Microsoft.Extensions.FileProviders.Physical.dll, but its assembly version is 3.1.6.0.
The console application and its dependencies are a part of a bigger project in said folder, with a total of over 1,200 DLLs.
In .NET Framework, I'd have used a binding redirect to use the present version 3.1.6.0 of the indicated assembly. In .NET Core, though, I understand these binding redirects are not a thing anymore. Thus, I'm not sure how to proceed, or how to even find out why the runtime thinks it needs to load Microsoft.Extensions.FileProviders.Physical.dll.
I may have found a partial solution that loads the version-mismatched assembly nonetheless (see observation (6) below), but then, I'm still getting a FileNotFoundException, this time for Microsoft.AspNetCore.Mvc.Abstractions.
Some observations and attempts to solve this:
(1) None of the > 1,200 .csproj files contains the string "Physical".
(2) More than 400 of the .deps.json files mention "Microsoft.Extensions.FileProviders.Physical.dll", all of them referring to version 3.1.0.0.
(3) All of the respective DLLs are loaded in an ASP.NET Core application where the version mismatch appears to cause no issues.
(4) The .deps.json file of my console application itself does not mention "Microsoft.Extensions.FileProviders.Physical.dll".
(5) Putting the right version of the file (3.1.0.0) into the directory where the .exe file resides and from where the .exe file is also executed does not change anything. The FileNotFoundException still occurs, still complaining about an absence of "Microsoft.Extensions.FileProviders.Physical.dll", version 3.1.0.0.
(6) Based upon the information on assembly resolution in .NET Core provided in a CodeProject article, I have attempted to force loading of the assemblies from the same directory myself (preliminary code, relying on the working directory):
AssemblyLoadContext.Default.Resolving += (context, name) =>
{
var dllPath = System.IO.Path.Combine(Environment.CurrentDirectory, name.Name + ".dll");
if (File.Exists(dllPath))
{
return AssemblyLoadContext.Default.LoadFromAssemblyPath(dllPath);
}
return null;
};
This appears to help to some extent! Now, the "Microsoft.Extensions.FileProviders.Physical.dll" assembly, and plenty (more than 250) of others, can be loaded. But this fails once "Microsoft.AspNetCore.Mvc.Abstractions", 3.1.0.0, needs to be loaded, which is not actually anywhere around the .exe file. Apparently, it must be loaded from somewhere else (?)
(7) While the above appears to provide a partial solution concerning the version mismatch, our entire source code contains no other occurrence of "AssemblyLoadContext". Therefore, the ASP.NET Core application apparently avoids the version mismatch issue using some other mechanism.
(8) Building my console application with build output set to Diagnostic1 confirms the suspected behaviour for the "Microsoft.Extensions.FileProviders.Physical.dll" file (shortened excerpt of the output):
Dependency "Microsoft.Extensions.FileProviders.Physical, Version=3.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60".
Could not resolve this reference. Could not locate the assembly "Microsoft.Extensions.FileProviders.Physical, Version=3.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors.
For SearchPath "C:\(...)".
Considered "C:\(...)\Microsoft.Extensions.FileProviders.Physical.winmd", but it didn't exist.
Considered "C:\(...)\Microsoft.Extensions.FileProviders.Physical.dll",
but its name "Microsoft.Extensions.FileProviders.Physical, Version=3.1.6.0, Culture=neutral, PublicKeyToken=adb9793829ddae60"
didn't match the expected name "Microsoft.Extensions.FileProviders.Physical, Version=3.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60".
Considered "C:\(...)\Microsoft.Extensions.FileProviders.Physical.exe", but it didn't exist.
Required by "(A)".
Required by "(B)".
Required by "(C)".
In there, (A), (B), and (C) are assemblies of our own project. But as far as I can see, neither of their .csproj files mentions the text "Physical", so I do not understand why the DLL is allegedly being required by them.
(9) For the "Microsoft.AspNetCore.Mvc.Abstractions" assembly, diagnostic output says:
Dependency "Microsoft.AspNetCore.Mvc.Abstractions, Version=3.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60".
Could not resolve this reference. Could not locate the assembly "Microsoft.AspNetCore.Mvc.Abstractions, Version=3.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors.
For SearchPath "C:\(...)".
Considered "C:\(...)\Microsoft.AspNetCore.Mvc.Abstractions.winmd", but it didn't exist.
Considered "C:\(...)\Microsoft.AspNetCore.Mvc.Abstractions.dll", but it didn't exist.
Considered "C:\(...)\Microsoft.AspNetCore.Mvc.Abstractions.exe", but it didn't exist.
Considered "C:\(...)\Microsoft.AspNetCore.Mvc.Abstractions.winmd", but it didn't exist.
Considered "C:\(...)\Microsoft.AspNetCore.Mvc.Abstractions.dll", but it didn't exist.
Considered "C:\(...)\Microsoft.AspNetCore.Mvc.Abstractions.exe", but it didn't exist.
Required by "(B)".
Once again, (B) is an assembly (same as the (B) in (8)) of our own, but looking into the .csproj file does not reveal a single occurrence of "Mvc.Abstractions".
I have found a couple of questions that appeared to provide solutions, but none of them worked for me:
Assembly binding redirect in .NET Core - just points to another question (listed below).
Adding a bindingRedirect to a .Net Standard library - the answer points out that binding redirects do not exist in .NET Core, but that the .deps.json file can be used to resolve assemblies. It then goes on to describe .NET Framework binding redirects, without mentioning anything else on what to do with .deps.json in .NET Core.
Common practice to load the dependency(different version of dll) in program - the question is about .NET Core, but the answer applies to .NET Framework. For .NET Core, it links to one of the other questions listed here.
How can I add an assembly binding redirect to a .net core unit test project? - the answers to this question seem to suggest using binding redirects in app.config files, even though these are apparently not supported anymore in .NET Core according to another comment on that question. In any case, the suggested solution of adding
<PropertyGroup>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
</PropertyGroup>
to the .csproj file (uh, which one? I tried the one of my console application; is that the right one?) has no effect to my .deps.json files or the exception I keep getting, as far as I can tell.
Error System.IO.FileLoadException: 'Could not load file or assembly 'log4net, Version=2.0.8.0 in .NET Core - in this case, the correct DLL was available in the right version, it was just not copied to the appropriate output folder.
.NET Core 3.1 - Could not load file or assembly System.Runtime, Version=4.2.2.0 - the solution in this case seemed to be to use another library/library version that would fit with the assembly reference. I do not think that is a viable way for me, as replacing the Microsoft.Extensions.FileProviders.Physical assembly might just cause any kinds of conflicts or issues in any of the > 400 of our assemblies that apparently somehow use the file, according to the .deps.json mentions.
Why is my .NET framework app looking for the wrong version of the .NET core/standard platform extension assembly, and how do I fix it? - it seems this question's OP just accidentally stepped into the .NET Core topic, while they were actually working in a .NET Framework context.
FileNotFoundException when referencing DLL in .NET Core Application - this issue was centered around deficiencies in earlier .NET Core versions, which do not apply to .NET Core 3.1 anymore.
FileNotFoundException with indirectly (.net to .net standard to NuGet) referenced DLL - this appears to have been another case of the correct DLL file being available, just not in the right location.
Can I control .NET Core assembly redirects programmatically? - once again, comments in this question point out that binding redirects are not a solution in .NET Core. Moreover, the answer appears to apply to compile time. As none of our .csproj files mentions the files with which I am observing a version mismatch, I suspect it is referenced from within one of the 3rd party libraries we are using and thus compile-time solutions may not be applicable.
How can I make the runtime load version of 3.1.6.0 of the indicated assembly rather than the requested version 3.1.0.0? Alternatively, how do I find out how the runtime does it when running the ASP.NET Core application?
1: in VS2019: Tools -> Options -> Projects and Solutions -> Build And Run -> MSBuild project build output verbosity -> Diagnostic

Related

Dynamically loaded .NET core library with .NET framework dependencies doesn't load the successfully, but in project reference does

I'm loading a .NET framework DLL from an OEM's website into a .NET 6.0 wrapper DLL.
Then I load that wrapper into my .NET 6.0 Winforms app:
App (.NET6.0) uses
DLL (.NET6.0) uses
DLL (.NET framework)
I get an error:
Could not load file or assembly 'XXX, Version=1.0.9.0, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified
But if I include a reference to DLL (.NET6.0) in App (.NET6.0), and still load it dynamically, it works.
The difference is the .deps.json - it lists the dependencies of the DLL (.NET6.0).
Building the app without reference to the DLL (.NET6.0) and then replacing the deps.json file, makes it work.
I think it must be something AssemblyLoadContext, but I don't know how to use it to load the dependencies as .NET framework. Or whatever is the difference.
You can see my code here:
https://github.com/pauldeboer1987/MCCDAQ_Wrapper
I'm wrapping the MCCDAQ dll from https://www.mccdaq.com/Software-Downloads
I expect to be wrapping many others, but this is just my example. I think any other .NET framework dll would cause this problem, but I'm not sure.
I added a ResolveEventHandler to currentDomain.AssemblyResolve
as described by Mattias S in
How to add folder to assembly search path at runtime in .NET?
That does the trick. See my updated repo.

What causes Microsoft.Practices.Unity assembly not to load?

I am running a project that had been running without issue for some time but recently started throwing an error stating,
"Could not load file or assembly 'Microsoft.Practices.Unity,
Version=2.1.505.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
or one of its dependencies. The system cannot find the file
specified."
I see that this assembly is for IoC/Dependency Injection support however I never explicitly added it to the solution; although I do see that it is in fact there.
When I check the version of the assembly it is showing the same version that is being referenced in the above error; so I cannot figure out why the file cannot be found by the project.
In effort of resolving the issue I've cleaned the solution, deleted my obj folder, rebuilt, removed and even reinstalled the assembly via nuget but the issue persists.
I've found somewhat similar issues reported here on SO but the proposed resolutions were either not applicable because it was not the same assembly reference as the one I'm having issue with OR it involved configuration of a XAML based application. This is ASP.NET.
The only other clue that I could find as to why I'm having the problem is that the targeted runtime framework of the assembly is v2.0.50727 and this application is .NET 4.5
Which would seem a reasonable explanation for the problem from my limited perspective except that the app was previously running without the problem.
I'd also mention that the assembly isn't explicitly being called from the block of code throwing the error; which is simply creating a web service client and calling a method.
long memberId = 1326728123;
ServiceClient sc = new ServiceClient("ServiceClientEndPoint");
var leadPackage = smc.GetLeadPackages(memberId);
So there could be other variables of this equation that may be attributing to the problem (e.g. Network blocking and etc)
I just wanted to make certain that I may not be missing something by running it past SO before wasting time going in the wrong direction for an answer.
Note that this could mean a number of things, including that one of the dependent assemblies of Microsoft.Practices.Unity could be loaded.
The first place searched is the GAC, if you are building and running on the same machine, this probably won't cause a problem because the runtime will also find the same library but if you are deploying, the project will sometimes bind to the GAC library whereas the production server might not have it installed and it will fail to run. CopyLocal=true should fix that but if you are deploying, you should check that the library is copied into the bin directory.
Secondly, you should open Microsoft.Practices.Unity.dll using reflector or ilspy.exe and see what other dependencies it has (other than the System.* libraries) since any other ones will need the same treatment as Microsoft.Practices.Unity i.e. adding to the project and copy local set to true.

OCR Reader WS Upgrade from .Net Framework 2.0 to 4.0

I have been tasked with converting an old .Net 2.0 application to 4.0 and am running into a build error related to a missing dependency.
The build error is as follows:
Error 1 Could not load file or assembly 'Atalasoft.dotImage.Ocr.GlyphReader.DLL' or one of its dependencies. The specified module could not be found.
I was thinking that I needed to find a newer version of this DLL but I wanted to see if anyone knew an easier method for resolving this first.
Any help would be great!
A .NET 4.0 or later assembly can reference and use an assembly built on the .NET 2.0 framework. The problem is that the compiler cannot find the assembly, not that the assembly is the wrong version. Try the following steps, this should clear up your problem:
Highlight the reference in the project and go the the properties tab (F4 shortcut). Check the path that is used to reference the assembly and verify that it is actually located there.
Check if the project requires a specific version of the assembly. Go to the same properties page like mentioned in step 1 and see if specific version is set to true, change it to false if this is not a requirement for you.
If you are using NuGet ensure that the latest assemblies have been downloaded if you are not persisting your references to the source repository. You check this by going to the nuget project references and in the top right corner there will be a message asking you if you want to restore all package references if they cannot be found.
If you are not using nuget for this and it still does not work then remove the reference and manually re-add it to the project.

Compiler error CS0433 - The type exists in both GAC and Temporary ASP.NET files

I have a situation where I get a runtime error when running ASP.NET MVC4. I recently migrated to MVC4 from MVC3.
Upon starting the debugger, I instantly get faced with this error message:
The type 'System.Web.Mvc.WebViewPage' exists in both
'c:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET
Files\promotionweb\20a5681f\9ce59023\assembly\dl3\29f671cf\37f0bcf2_4619d001\System.Web.Mvc.DLL'
and
'c:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Web.Mvc\v4.0_4.0.0.0__31bf3856ad364e35\System.Web.Mvc.dll'
I'm running in IIS 7.5, with a solution setup of the MVC project itself, another C# library plus a console application project.
I've tried all steps mentioned in this answer, descended from a similar question. However it doesnt help at all in my case.
I had some doubts it had to do to different compilations models, so I've tried compiling for x86 and AnyCPU, cleaning all catalogs as mentioned above in-between. Nothing seems to help.
Any ideas what might cause this interference between the GAC and my Temporary ASP.NET files?
Below is quite a story, but I think it might benefit someone else.
First of all, I opened my project inside Visual Studio 2013, and got a complaint. I followed a link from inside VS2013 (cannot find it) to a Microsoft site where it explained how to manually upgrade an MVC3 to MVC4 project. The steps I followed required manual changes to web.config.
One of the changes I made was to modify the version number of the System.Web.Mvc reference. Previously it was 3.0.0.0, and according to the guide 4.0.0.0 was the number to change to. Another step was to go into the NuGet package manager, search for ASP.NET MVC4 and install it. This downloaded version 4.0.0.1 of System.Web.Mvc, as I think that was the correct version of the time the guide was written.
Once done, I compiled the project and got into the never-ending loop of the runtime error in the question that I posted. My project was compiled against version 4.0.0.1 (which seems to be the correct version number according to a windows update). The compilation was correct, but I had the following line in my web.config:
<add assembly="System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
The application was compiled against 4.0.0.1, but was running and searching for 4.0.0.0 and found it in these two places:
c:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET
c:\Windows\Microsoft.NET\assembly\GAC_MSIL
and thew the error. I still do think this part is strange.
My solution was to modify the web.config, changing the assembly reference version as mentioned, and the binding redirects for System.Web.Mvc.
Some other sources:
System.Web.Mvc not functioning as expected after Windows Update
System.Web.Mvc broken after security update
I once had this error. I noticed that it is important that the reference in the project and the add assembly-tag in web.config is the same. What I did was remove the reference to the assembly that was not the same as in web.config and then adding reference with the correct version. I assume you could also do it the other way around.

Could not load file or assembly NLog

Error: http://pbrd.co/1vTqOTb
I am getting an error in my XAML in my WPF project:
"Error 11 Could not load file or assembly 'NLog, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=5120e14c03d0593c' or one of its dependencies.
The system cannot find the file specified. MainWindow.xaml 73 9 TestApp"
I have searched the entire solution and cant find any 'NLog'
I have tried to add the NLog dll to each of my projects in the solution but it makes no difference.
Any idea?
Turned out to be the NLog was .Net 4.0 and the project was .Net 4.5
I changed the project to 4.0 and the other dependent project to 4.0 and its working.
Thanks!
Whenever you reference another library, there's the chance they will need some other library. When you reference WPF, there are a lot of underlying libraries that get pulled up.
First, make sure that the DLLs you've referenced are set to "Copy Local = True" under their Properties. Also make sure they have the same PublicKeyToken as your error - if they're referenced by strong name (and most of .NET is) a slightly different version won't be read as the correct file.
The other thing you should consider is checking whether the DLL exists in your GAC, and manually installing it if it doesn't. This can often be the cause of such frustrating errors due to a misinstalled sdk (I once has the same issue with the Blend libraries)

Categories