microsoft / MSBuildLocator

An API to locate MSBuild assemblies from an installed Visual Studio location. Use this to ensure that calling the MSBuild API will use the same toolset that a build from Visual Studio or msbuild.exe would.
Other
216 stars 83 forks source link

Loading of Microsoft.Build.Framework.dll seems broken in public release 1.4.1 #125

Closed TomKuhn closed 3 years ago

TomKuhn commented 3 years ago

1.3.2 is fine, and works. I have recently upgraded my project to use 1.4.1 and now I am getting obscure msbuild errors:

C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\Microsoft.Common.CurrentVersion.targets(1657,5): error MSB4127: The "GetReferenceNearestTargetFrameworkTask" task could not be instantiated from the assembly "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\CommonExtensions\Microsoft\NuGet\NuGet.Build.Tasks.dll". Please verify the task assembly has been built using the same version of the Microsoft.Build.Framework assembly as the one installed on your computer and that your host application is not missing a binding redirect for Microsoft.Build.Framework. Unable to cast object of type 'NuGet.Build.Tasks.GetReferenceNearestTargetFrameworkTask' to type 'Microsoft.Build.Framework.ITask'.

The invalid cast made me think two libraries are using different versions of Microsoft.Build.Framework.dll and the types aren't compatible. The modules window of the debugger confirms this:

Load#1: Correct location

Microsoft.Build.Framework.dll Microsoft.Build.Framework.dll C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\Microsoft.Build.Framework.dll Yes No Skipped loading symbols. 73 15.09.21.664 0000018BA7C50000-0000018BA7C6E000 [41964] Launcher.Console.exe [2] MicrosoftBuild

Load#2: Incorrect location / version:

Microsoft.Build.Framework.dll Microsoft.Build.Framework.dll C:\windows\Microsoft.Net\assembly\GAC_MSIL\Microsoft.Build.Framework\v4.0_4.0.0.0__b03f5f7f11d50a3a\Microsoft.Build.Framework.dll Yes No Skipped loading symbols. 91 4.8.4084.0 built by: NET48REL1 24/11/2019 08:27 0000018BA7EF0000-0000018BA7F0A000 [41964] Launcher.Console.exe [2] MicrosoftBuild

So I think the assembly resolver is not working properly anymore. This is how I initialize the build locator:

private static void Initialize(string[] arguments) { var allInstances = MSBuildLocator.QueryVisualStudioInstances(VisualStudioInstanceQueryOptions.Default); var requiredVersionInstance = allInstances .Where(instance => instance.Version.Major == _visualStudioMajorVersion && instance.Version.Minor == _visualStudioMinorVersion) .FirstOrDefault();

        if (requiredVersionInstance == null)
        {
            throw new BuildException($"Unable to find an installed version of Visual Studio with " +
                $"major version '{_visualStudioMajorVersion}' / minor version '{_visualStudioMinorVersion}'");
        }

        MSBuildLocator.RegisterInstance(requiredVersionInstance);
    }
TomKuhn commented 3 years ago

Actually I might have figured it out and this is not a bug. When I upgraded version I didn't load the new version's props file into my startup project, so I lost the binding redirects.

Forgind commented 3 years ago

If that didn't work, have you tried unGAC-ing MSBuild? Modern versions should not be in the GAC. To get it out, you can install 16.8 or run the following command: gacutil –u <assemblyName> for each relevant MSBuild assembly: Microsoft.Build, Version=15.1.0.0, Microsoft.Build.Engine, Version=15.1.0.0, Microsoft.Build.Framework, Version=15.1.0.0, Microsoft.Build.Tasks.Core, Version=15.1.0.0, Microsoft.Build.Utilities.Core, Version=15.1.0.0, Microsoft.Build.Conversion.Core, Version=15.1.0.0

Does that help?

Forgind commented 3 years ago

Closing as presumably a GAC issue.