microsoft/MSBuildLocator

NuGet version conflicts

xen2 opened this issue · 6 comments

xen2 commented

Our project references NuGet API directly.
However, since MSBuild also needs its own specific version of NuGet, this results in runtime conflicts (i.e. Error: The "ResolvePackageAssets" task failed unexpectedly.).

So far I found a workaround which is to override AssemblyLoadContext.Default.Resolving but then internally do the assembly loading in another AssemblyLoadContext.

            var vsi = MSBuildLocator.QueryVisualStudioInstances().First();
            var alc = new AssemblyLoadContext("MSBuild");

            AssemblyLoadContext.Default.Resolving += (assemblyLoadContext, assemblyName) =>
            {
                string path = Path.Combine(vsi.MSBuildPath, assemblyName.Name + ".dll");
                if (File.Exists(path))
                {
                    return alc.LoadFromAssemblyPath(path);
                }

                return null;
            };

It seems MSBuild works fine with that, and I can still use my PackageReference to a specific version of NuGet.
I am still investigating if there's a better way to do that.

Would the project accept such changes?
Otherwise just having the ability to pass a custom AssemblyLoadContext or custom resolver rather than using Assembly.LoadFrom in RegisterMSBuildPath might be enough!

Are you seeing this with a specific version of the .NET SDK? This sounds like something we're hoping to fix in MSBuild itself in dotnet/msbuild#6377 that would affect 5.0.300 and 6.0.100-preview builds.

I'm hesitant to take this change because MSBuild does some internal ALC manipulation relating to loading plugins like task assemblies, and I don't know if this would confuse it. But I don't know of any problem that it would cause so "working well for you" is a pretty good data point.

xen2 commented

Interesting, thanks for the link to the MSBuild issue, it might be related.

I could do a simple repro project with the following versions:
Visual Studio 2019 latest (.NET 5.0.202)

    <PackageReference Include="Microsoft.Build" Version="16.0.461" ExcludeAssets="runtime" />
    <PackageReference Include="Microsoft.Build.Utilities.Core" Version="16.0.461" ExcludeAssets="runtime" />
    <PackageReference Include="Microsoft.Build.Locator" Version="1.4.1" />
    <PackageReference Include="NuGet.Commands" Version="5.8.0" />

The repro project uses NuGet 5.8.0, then call MSBuild Locator and run a Restore on a project. The restore fails due to NuGet 5.8.0 being already loaded (5.9.x is shipped with .NET 5.0.202).
Let me know if you want me to cleanup and post the repro project.

I also had a nuget package problem, seemed to be the same problem, details: dotnet/roslyn#61454
@rainersigwald could you help confirm if it's the same problem, if yes, I would close the issue, thanks

That definitely looks like the same problem. You can try if ExcludeAssets="runtime" on that PackageReference fixes it for you.

@baronfel thanks, I tried while it did not work for me 😭

Does this ticket belong to MSBuild.Locator? I can see the attached tickets in Roslyn repo.