Search code examples
c#buildroslyn

Getting '"Microsoft.CSharp.Core.targets" was not found' when compiling with Microsoft.Build.Execution.BuildManager.DefaultBuildManager


I have a set of projects that successfully compile and build on Visual Studio 2022.

I'd like to build them programmatically. For this purpose, I created a builder project, that makes use of Microsoft.Build.Execution.BuildManager.DefaultBuildManager:

            var pc = new ProjectCollection();

            //There are a lot of properties here, these map to the msbuild CLI properties
            var globalProperty = new Dictionary<string, string>() {

                { nameof(DTOBuildGlobalProperty.OutDir), BuildGlobalProperty.OutDir },
                { nameof(DTOBuildGlobalProperty.Platform), BuildGlobalProperty.Platform },
                { nameof(DTOBuildGlobalProperty.Configuration), BuildGlobalProperty.Configuration },
                { nameof(DTOBuildGlobalProperty.TargetFramework),$"clean,{BuildGlobalProperty.TargetFramework}"}
            };

            BuildManager.DefaultBuildManager.ResetCaches();

            var bp = new BuildParameters(pc) {
                Loggers = new List<Microsoft.Build.Framework.ILogger>() {
                    new FileLogger() { Parameters = $@"logfile={BuildGlobalProperty.OutDir}\buildme.log;append" }
                }
            };

            var brequest = new BuildRequestData(path
                , globalProperty
                , null
                , new string[] {
                    BuildGlobalPropertyTargetToBuild.Restore.ToString(),
                    BuildGlobalProperty.TargetToBuild.ToString()
                }
                , null);

            var bresult = Microsoft.Build.Execution.BuildManager.DefaultBuildManager.Build(bp, brequest);

This code produces a log file with the messages like:

error MSB4019: The imported project "bin\x86\Debug\Roslyn\Microsoft.CSharp.Core.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.

and the build failed, of course.

Worth to note that this code used to work with Microsoft.Build version 15.1.0.0 added as phisical .dll; when I attempted to upgrade my builder project to use packageReferences and added Microsoft.Build version 17.8.3 from Nuget, I started to notice the problem.

How can the code above be corrected, in order to work?

Notes:

I already checked similar questions and answers (like \MSBuild\16.0\Bin\Microsoft.CSharp.targets file not found), unsuccessfully.


Solution

  • Before you go invoking MSBuild builds, you need to use MSBuildLocator to specify the version being used. This sets various bits of environment for MSBuild that specifies where certain tasks and targets get loaded.