Dependency problems after update nuget packages of a VISX project - c#

I'm creating a VISX project. It runs normally, but after I update all it's nuget packages, it start to show errors when I try to run it in the Visual Studio Experimental Instance.
I tried to revert the packages, but it seems that some packages versions are no longer available for download.
The main reason is that the VISX can't load the Microsoft.VisualStudio.Threading assembly after the dependecies are updated.
I tried adding the assembly to the package's Assets too. The VISX can load it now, but can't find the following method in the AsyncPackage class, like it would be loading the wrong assembly version.
JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
There's also the same error (assembly not found) for the Newtonsoft.Json dependency.
Can someone help me with this?
I zipped everything and upload in my onedrive: https://1drv.ms/u/s!AmhLdtS8gKjrl71Vmnp85m4ZPUILgw
I included all packages, since there's a chance that who download the project could not execute it because the packages could not be downloaded from nuget.org.
To simulate the error, just update the dependencies.
Update 1
As suggested, I was able to redo the entire project using "package reference" to target dependencies.
The visx builds and work, but the problem with the dependency for Newtonsoft.Json still occurs.
Also, I tried adding another dependency from a nuget package that I created, and the same error occurs too.
I wrote a piece of code that uses JsonConvert just to make use of the dependency.
When I execute the "TestCommand" from VS Experimental instance, them the error popups.
Link for the second project in my onedrive:
https://1drv.ms/u/s!AmhLdtS8gKjrl71ZCd1WIYNDTZaSCw

Related

Could not load file or assembly 'Azure.ResourceManager.ResourceGraph

Getting following error: Could not load file or assembly 'Azure.ResourceManager.ResourceGraph, Version=1.0.0.0, Culture=neutral, PublicKeyToken=92742159e12e44c8'. The system cannot find the file specified.
Have tried cleaning, removing and reinstalling the package, completely removing the .nuget folder, starting a new project and repulling the repo, eliminating all related code and references, various entries suggested on the InterWebz into the project file, but same error, over and over.
Something slightly suspicious: the package version on NuGet is 1.0.0 but the error references Version=1.0.0.0 (extra zero).
Note that the package works fine in a different solution.
Solved but in a flummoxing manner. The solution is a project that makes a DLL and a demo project that uses that DLL to illustrate how to use the DLL in practice. The Demo project does not call ResourceGraph at all, only the DLL does. But when I added the ResourceGraph to the Demo project, the error went away. That's not how it's supposed to work, right? Or am I misunderstanding how dependencies work. If a Project calls a DLL that has dependencies, does that Project also need to add the packages that the DLL uses? I have not referenced the ResourceGraph package with "using" in the Demo program, but adding the package still fixed it. Thoughts?

How to trace resolving process of nuget package references

I have a solution with multiple projects in it (~400). A lot of them are using newtonsoft.json library. Some of them are using different version of the library. In a host project for web app, there is no direct reference to newtonsoft.json. Also, I believe, there are dependencies to packages that depend on newtonsoft.json. However, in bin folder of that project I began getting newtonsoft.json 9.0 instead of newtonsoft.json 11.0 as it used to be. And it causes load exception in runtime due to invalid version. If I include direct reference to newtonsoft.json 11.0, it still puts version 9.0 in the bin folder even if I clear all bin,obj folders. I use PackageReference for managing dependencies, and everything is in .net 4.6.1; I use binding redirects to resolve issues with different versions of the same library.
My question is if there is a way to diagnose how particular dll of package ref appears in bin folder? I would like to see some sort of comprehensive trace of dependency resolution so that I can fix it without using "trial and error" approach.
Upd.
Actually, thanks guys for pointing to structured logging. You are the best! So the issue was that one of the project had <OutputPath> pointing to the bin folder of the host project. So when the project was built, it was overriding binaries in the host project. Apparently, build order has changed due to continuous reference shuffling and the project with wrong <OutputPath> started building last. To find this out 1) I Newtonsoft.Json was recorded in DoubleWrites section 2) analyzing location from double writes I found out in _CopyFilesMarkedLocal section
Copying file from "\VenomousProject\bin\Debug\Newtonsoft.Json.dll" to "HostProject\bin\Debug\Newtonsoft.Json.dll".
That was it.
You can try MSBuild Binary and Structured Log Viewer (https://msbuildlog.com/)
build the project from command line with msbuild -bl - you will get msbuild.binlog
open the binlog with the log viewer and use the dll name as a search term
inspect all records related to the dll and backtrack a place (project and msbuild' target) where the wrong file version is taken.
With PackageReference, NuGet will write a file named project.assets.json in the project's obj folder. This file is used by the rest of the build to determine what files from packages should be included in the build, but it also contains a list of all the packages that were selected, what version was selected, and what dependencies each package has (package id and version). This is the closest thing to dependency resolving debugging that NuGet has.
In the file, search for "Newtonsoft.Json/, and you should find which version of Newtonsoft.Json that NuGet selected. Remove the / and replace it with ", and you can find all the packages that have dependencies on Newtonsoft.Josn. Search for newtonsoft.json.dll to find all the packages that ship that dll in its package (sometimes package authors perfer to ship multiple dlls in their package, rather than adding dependencies, which prevents NuGet from being able to version selection.
If there are multiple packages with which contain a dll with the same filename, NuGet will tell MSBuild about all of them, and it's up to MSBuild to select which one to use (pass to the compiler and copy to the bin/publish directory). As #Serg wrote in their answer, you can use binlogs (with the -bl argument on any MSBuild command, including dotnet restore or dotnet build). NuGet's inner workings are not output to MSBuild, so when your package graph has multiple packages that list Newtonsoft.Json as a dependency, it won't tell you why NuGet chose a specific version, but binlogs are very useful at debugging other build related issues.

could not load file or assembly exception NET 5/6 of NuGet package for NET Standard

I'm at the end of my rope trying to figure out why my working DLL cannot load a NuGet package that it could always load before (like for a whole year). My system has 70 NET 6 projects and half a dozen of them use the same NuGet package to read XML files. Recently (a few months ago) I upgraded everything to NET 6, and even after that upgrade, everything worked fine.
But now, one of my C# class libraries generates an exception in a constructor because it can't find the NuGet package that sits right beside it in the filesystem app folder where everything is loaded from. The error message was:
.ctor Could not load file or assembly xxx blah blah. The system could not find the file specified.
For what it is worth, here is a trace of the build options in the batch file that I have been using for months.
Deleting hscore\hscore\bin Deleting hscore\hscore\obj Deleting
hscore\hscore\packages "C:\Program Files\Microsoft Visual
Studio\2022\Community\MSBuild\Current\Bin\msbuild.exe" -nologo -m
-V:minimal -t:clean;restore;publish /p:Platform=AnyCPU /p:PlatformTarget=AnyCPU /p:Configuration=Debug
/p:TargetFramework=net6.0-windows7.0 /p:RuntimeIdentifier=win-x64
/p:SelfContained=false /p:PublishProtcol=FileSystem
/p:DeleteExistingFiles=true /p:PublishDir=c:\dev\holding\core.plt
-nowarn:MSB3305 c:\dev\products\hscore\hscore\hscore.csproj
Determining projects to restore... Restored
c:\dev\products\hscore\hscore\hscore.csproj (in 874 ms).
hscore -> c:\dev\products\hscore\hscore\bin\Debug\net6.0-windows7.0\win-x64\hscore.dll
hscore -> c:\dev\holding\core.plt\
I have done the following to debug it, without success:
deleted the bin/obj folders of the failing class library
checked the target framework of all projects (= net6.0-windows7.0)
checked the runtime identifier of all projects (= win-x64)
checked the build configuration (Debug, AnyCPU)
removed and re-added the NuGet package (with a specific version)
the Nuget package depends on NET Standard, compatible with NET 6
and I use the same version in other NET 6 programs that are working fine
restored and rebuilt the DLL
published it to the destination folder where it is run from
checked that the expected Nuget package is there (it was)
and yet it still fails to find the Nuget package
I tried to trace DLL loads of the process with the SysInternals Process Monitor, but I am not good enough to do that (if it is even possible). I can filter events to see the parent app process load, but the failing DLL is called by the parent process and I don't know how to see the search paths it is using to find the Nuget package.
I want to believe that the problem is a version mismatch between NET 5 and NET 6 and the version of the Nuget package sitting in the folder, because I once had a problem like that. For example, if I had a NET Framework version of the Nuget package, it would not be "found" by a NET 5 DLL that wanted to load it. (I am NOT saying that is my problem, because I have no NET Framework projects anymore.)
The most recent thing I have been working on is the build system and options. I can build the whole system with batch files or with parallel builds (when the system is working). I use the same msbuild options in both cases, and the batch method has been reliable and shows no build errors, no publish errors, all the correct build options, and no warnings or errors whatsoever.
The Nuget package pulls in 10 or 20 dependencies, but that is all automatic, and the package works with other console programs and apps that are working fine. So, I don't think there is anything wrong with Nuget package. All the working apps use the same Nuget package from the same runtime folder. I don't know why this one DLL is having a problem. AND I have not changed anything in the failing DLL class library for months (and it has been working fine).
Does anyone have suggestions on what else I might try to debug the problem and get the system working again? Thank you.
UPDATE - New version and build, but still a runtime failure.
Just to be sure, I upgraded the Nuget package that could not be found to the latest version and replaced all references in my 70 projects to the new version. Then I rebuilt the system (no warnings, no errors). But that did not make a difference. Now the new version cannot be found.
All unit tests of the code in question work flawlessly in VStudio, presumably because VS loads the Nuget package properly. I am mystified and would appreciate thoughts on how to proceed. Thank you.
UPDATE 2 - installed 'dotnet-trace' and traced DLL loads
I found a page that described how to dotnet tool install --global dotnet-trace and then captured a trace of my app trying to find the elusive Nuget package that is sitting right beside the requesting DLL. Although I could my app loading various app DLLs (and tons of system DLLs) with found pathnames, the trace showed nothing useful about the Nuget package.
The trace entries show the system searching in stages FindInLoadContext, then ApplicationAssemblies, then AppDomainAssemblyResolveEvent. After that, the system throws an exception because it can't find the Nuget package.
I would have thought the system FindInLoadContext would find it in the same folder as the executing and requesting assemblies, but it seems not so.
Ideas? I'm lost. And everything used to work fine.
UPDATE 3 - A small console app calls the DLL and it finds the Nuget package
The problem scenario in this question is: WindowsFormsApp -> loads MyCore.dll and calls new MyCore.MyObject(), which in the constructor tries to read some XML files using MyUtils.dll, which tries to reference the mystery Nuget package for reading XML files. MyUtils.dll cannot find the package, no matter what I do.
I wrote a small console program to load MyUtils.dll and called the exact same MyUtils.ReadMyXmlFiles API to read the files. The console app (actually, the system assembly loader) correctly found the Nuget package and read the XML files properly. This all occurred in the same folder that contains the Forms app and the Nuget package.
The only difference now is that the WindowsForms app calls an intermediate DLL that calls a constructor that references MyUtils.dll.
Could the intermediate DLL + constructor call be changing the Assembly Load Context (FindInLoadContext search rules) for the Nuget package load operation? Very strange.
The overall problem was that my Windows Forms app failed during boot (in the Form_Load event) because a Nuget package could not be found to read some XML configuration files.
Four assemblies were involved in the problem. Assembly1 (the app) called Assembly2 (.. new Assembly2Object()), whose constructor called an Assembly3 method (utilities.ReadXMLFile) which called Assembly4 (NugetPackage.XMLReader).
You can see that only Assembly4 references the Nugetpackage which could not be found. Normally, there should be no reason for Assemblies 1 or 2 to know about the existence of the NugetXmlReader used by Assembly3. But, the exceptions and assembly load traces of dotnet-trace and procmon clearly showed that Assembly3 (utilities.ReadXmlFile) could not find the NugetPackage at runtime, even though the right package was in the folder beside the executing assemblies (1->3).
The "solution" for my case was to add a Nuget package dependency to
Assembly1 (the WinFormsApp). As soon as I did that, Assembly3 (utilities.ReadXmlFile) could find Assembly4 (Nugetpackage).
My working theory is that during a WinForms boot sequence (including the Form_Shown event), the AssemblyLoadContext from Assembly1 is used to look up all assemblies in any call chain (like Assembly2 calling Assembly3 calling NugetPackage4).
Because the load context of Assembly1 has no reference to NugetPackage, and because the .deps.json file for Assembly1 is present (the doc says it is used to form the load context), Assembly3 - using the assembly load context for Assembly1 - could not find the NugetPackage.
When I added a dependency to Assembly4 (Nugetpackage) to Assembly1, then the assembly load context from Assembly1 was used by the System AssemblyLoader FindInLoadContext phase to search for (and find) the NugetPackage4 wanted by (the referencing assembly) Assembly3.
I used to think that each assembly in a calling chain would have its own assembly load context used by AssemblyLoad/FindInLoadContext. But I think that no longer. At least for my case of a Windows Forms app booting up, the assembly load context from the top-level app is being used to look up Nuget packages far down the calling chain.
It's worth repeating that my little test console apps always found the Nuget package without adding the package as a dependency to the top-level console program. I wrote console programs to test the calling chain from the bottom up: Test1) console calls Nuget directly - found; Test2) console (w/o Nuget dependency) calls Assembly3 - Nuget found; (Test3) console (w/o Nuget dependency) calls Assembly2 - Nuget found.
Then I wrote a skeleton WindowsFormsTestApp to call Assembly2 (just like the console program did) - Nuget NOT found. When I added a Nuget dependency to the WindowsFormsTestApp - Nuget was found by Assembly3.
The final step was to add a Nuget package dependency to the WinFormsApp that started this whole mess. Presto! Assembly3 found the Nuget package immediately.
My (unproven) belief is that somewhere along the line of upgrades from NET 5 - NET 6 (several SDK versions of each one), the assembly load context rules changed somehow. I could be wrong, but I lean toward this belief because my code from App->Assembly2->Assembly3->Nuget did not change during several months of successful operation. And just a couple of weeks ago after another NET 6 SDK upgrade, things broke.
Hopefully, this record might help someone someday. It seems completely unintuitive to me to add a Nuget package dependency to the top-level Forms app to help Assembly3 find a Nuget package sitting in the same folder as all the other assemblies.
After all this, I am coming around to the idea that the top-level app must/should include dependencies on anything the app ever calls, including packages used by dependent assemblies. (Although I am still puzzled as to why the code worked for months before without the Nuget package dependency.)

Error loading EntityFramework 4.3.1

I created an MVC application in C#. I created a new project in my solution called PhoneDomain. The purpose of this is to separate my data and domain layer from the actual problem. I right clicked on the project and went to "Add Library Package Reference" and I attempted to add the EntityFramework package (version 4.3.1). It said "Operation Failed" "This package contains an init.ps1 file and needs to be installed from the Package Manager Console".
So I opened the Package Manager Console in Visual Studio and typed the following into the console window:
install-package EntityFramework -project PhoneDomain
After a couple seconds, it installed the package and said Successfully added 'EntityFramework 4.3.1' to PhoneDomain
The problem is, when I run my application, I get the following error message: Could not load file or assembly 'EntityFramework, Version=4.3.1.0, Culture=neutral' or one of its dependencies. The system cannot find the file specified.
The reference in the PhoneDomain is definately there and the the Copy Local property is set to True.
Can anyone tell me what is going on here?
Check your web.config for assembly references. There may be a rogue reference in there.
UPDATE:
Also make sure ALL projects have the necessary reference...

"An assembly with the same simple name has already been imported" error without duplicate reference

I'm getting the following error:
error CS1704: An assembly with the same simple name
'Interop.xxx.dll, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null has already been imported. Try removing one of the
references or sign them to enable side-by-side.
Everything I've seen says that I am referencing two assemblies with the same name and I need to remove one of them. However, I've checked and I'm only referencing it once.
This also only happens when I'm using msbuild to build from the command line on my dev box. If I build through Visual Studio or do a clean build on our CI server I don't see this error.
I've tried completely removing all of my source and building from scratch to more closely resemble the build machine but no luck.
So it looks like I can't read today!
The project had a reference to the Interop and a COM reference that generated the "same" interop. So there were two and I just didn't search very well. I still don't understand why it worked in other places but this did fix it.
In the Error List window, the project that was triggering this error was listed in the Project column. I got around the error by doing the following:
I unloaded the listed project (right-click => Unload Project)
Opened the XML for edit (right-click the unloaded project => Edit {ProjectName.csproj}).
Searched for the offending .dll, and noticed it was listed multiple times in the XML
Removed the entire Reference tag related to the offending dll, and did so for every copy of the reference except the first one listed
The reason it was listed multiple times was because several referenced libraries used that dll. This shouldn't be a problem, in and of itself, so I'm not sure what caused this error to suddenly pop up for me. I'll update this answer if I figure that out.
In my case the duplicate entry was caused by a NuGet package reference and a direct file reference to the same assembly in the packages folder. I am not sure how the project got into this state, but unloading the project and searching the XML file for the offending assembly name resolved the issue for me.
Note that in my case this started happening after updating a NuGet package to a newer version with no other changes to the project, so this maybe caused by a bug in NuGet.
If this is a web project, are there any strong-named references to the other version there? Those won't show up as a project dependency, but will cause a run-time error like you describe. Hope that helps
I had this problem but in my case, I had an old copy placed in the current folder for the EXE loading my component, that was loaded together with the current one, that was loaded by hand from my projects folder. Deleting that old copy solved my problem.
I used Debug > Windows > Modules window to see which modules were loaded at that time and that solved my problem.
For others facing the same as me: if building via command line using property AssemblyName, it will overwrite all assemblies generated by all solution projects - in other words, you will end up with (N -1) assemblies named the same where N is the no. of projects - the startup one (which generally will generate an exe).
This happens because all build command line properties are global and overwrite any project-specific setting. See this and this.
From the msdn link mentioned above:
Global properties are properties that are set by using the
/property switch on the command line, or properties that are set by
the integrated development environment (IDE) before a project is
built. These global properties are applied to all projects that are
built by using this Engine.
In my specific case, where Jenkins is the CI tool, I ended up adding a windows batch command at the end to rename the .exe only to what I originally intended when passing the AssemblyName parameter.
For those developing UWP projects that have project references that include specifically the Microsoft.Windows.SDK.Contracts nuget package (or other dependencies that reference it), this is a common error when the version of the SDK contracts is targeting a different version of the runtime to how your project is configured.
For instance, when targeting Windows 10, version 1903:
Any dependencies or reference projects should target or at least support the same runtime version.
it is common thought process to update all NuGet packages when a new stable version is available, but this is not always a helpful practise on its own. Just because a new stable version of a package is available does not mean that you should or that you can easily use that version.
Even though this package for SDK contracts has a stable update, it is not compatible with my main project configuration, Nuget does not know this so it allows the update.
This package is specifically designed to provide windows dlls for project types that DO NOT have windows platform targeting support, it copies the same dlls that are included by the UWP targeting config. By installing later versions of the package the references from the satellite project will be included in the output along with those provided due to platform targeting, ultimately causing OPs error.
There are similar SDK and targeting packs for Windows IoT Device Runtimes, this information should help you identify and resolve those issues if you get stuck on this issue as my team often does :)
In my case, the issue was on wrong characters in the ProjectReference section of my csproj file.
Background
I have a project that references another library I maintain, which I publish as a NuGet package.
Whenever I make changes to my library, I usually reference the local dll in my project to test and make sure everything looks good before I publish the library as a NuGet package.
When testing, I just comment out the PackageReference line and uncomment the ProjectReference one so it references my local dll, like so:
<ProjectReference Include="..\..\my-class-library\MyClassLibrary.csproj" />
<!--<PackageReference="MyClassLibrary" Version="2.0.1"/>-->
Root cause
I had the slashes inverted, so I was using / rather than \ in the path, like so:
<ProjectReference Include="../../my-class-library/MyClassLibrary.csproj" />
Once corrected, the issue went away.
Try this instead: remove Interop.xx.dll from the reference section in Solution Explorer and Rebuild the project
In our case this error was shown when we had a duplicate reference inside the .csproj file (although I have no idea how this happened).
The difference to an already posted answer is that, in our case, one was a project reference and another one was direct binary reference to a dll.
Once we removed one of those, project correctly compiled.

Categories

Resources