使用 Microsoft.Build 以编程方式构建项目失败

Building Project Programmatically Fails Using Microsoft.Build

我将以下三个软件包安装到我的控制台应用程序中:

Microsoft.Build
Microsoft.Build.Framework
Microsoft.Build.Tasks.Core
Microsoft.Build.Utilities.Core

并且我尝试用下面的方法搭建了一个项目:

        static void Build(string projectPath)
        {
            var logger = new ConsoleLogger(LoggerVerbosity.Normal);
            logger.ShowSummary = true;
            var manager = BuildManager.DefaultBuildManager;

            var projectInstance = new ProjectInstance(projectPath);
            var result = manager.Build(
                new BuildParameters()
                {
                    DetailedSummary = true,
                    Loggers = new List<ILogger>() { logger }
                },
                new BuildRequestData(projectInstance, new string[] { "Build" }));
            var buildResult = result.ResultsByTarget["Build"];
            var buildResultItems = buildResult.Items;
        }

然而,在我 运行 代码之后,我得到了下图描述的错误:

为什么会发生这种情况,我该如何解决?

我认为您没有使用正确的 MSBuild 版本。尝试在您的 .proj 中明确设置变量:

<MSBuildExtensionsPath>C:\Program Files (x86)\MSBuild</MSBuildExtensionsPath>

BuildRequestData 构造函数重载之一支持名为 "toolVersion" 的参数。由于您使用的是 Visual Studio 2017,请将其设置为“15.0”。

编辑: 我不再使用 .Net Framework 提供的 MSBuild 版本(位于此处): System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory()

C:\Windows\Microsoft.NET\Framework\v4.0.30319

相反,我使用的是位于此处的那个:

C:\Program Files (x86)\MSBuild\{version}\Bin

此版本提供额外参数 LangVersionDeployOnBuild

看来最好的解决办法是在 Process class 中使用 MSBuild 命令行。工作示例如下:

            var buildOutput = new List<string>();
            var buildError = new List<string>();
            var buildProcess = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName = "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\MSBuild.exe",
                    Arguments = projectPath + " /t:Rebuild /p:Configuration=Debug",
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    CreateNoWindow = true
                }
            };

            buildProcess.Start();
            while (!buildProcess.StandardOutput.EndOfStream)
            {
                buildOutput.Add(buildProcess.StandardOutput.ReadLine());
            }
            while (!buildProcess.StandardError.EndOfStream)
            {
                buildError.Add(buildProcess.StandardError.ReadLine());
            }

然后您可以使用输出来确定构建是否成功。重要的是你必须找到 MSBuild.exe 文件的正确路径,因为这个文件有多个版本,在我的例子中(VS 2017)正确的路径是示例代码中的路径。