2

我想通过使用以编程方式编译目标项目

Microsoft.Build.Evaluation.Project.Build()  

如果我需要编译的目标项目包含C#6.0 功能,例如安全导航运算符 ( ?.Operator),它会在这些代码行中准确给出错误。
如果我在目标项目中删除这些代码行,它编译得很好。

有谁知道如何以编程方式编译C#6.0 和 7.0 样式代码?
在构建我的运行时版本的项目中,构建版本Microsoft.Build.dll是 v4.0.30319,.Net框架版本是 4.6.2。

我添加了两个简单的项目。第一个控制台项目是编译的代码。第二个控制台项目是要编译的目标项目。通过注释掉第 15 行,编译成功,否则日志文件在该行显示错误。

编译的项目

using System;
using Microsoft.Build.Logging;


namespace CompilerApp
{
  class Program
  {
    static void Main(string[] args)
    {
        string projectfile = @"C:\temp\CompilerApp\MyCSharp7\MyCSharp7.csproj";

        UnloadAnyProject();
        Microsoft.Build.Evaluation.Project p = new Microsoft.Build.Evaluation.Project(projectfile);
        FileLogger loggerfile2 = new FileLogger();
        loggerfile2.Parameters = @"logfile=C:\temp\CompilerApp\myapp.msbuild.log";
        bool buildresult = p.Build(loggerfile2);
        if (buildresult)
        {
            Console.WriteLine("project compiled");
        }
        else
        {
            Console.WriteLine("project not compiled, check {0}", @"C:\temp\myapp.msbuild.log");

        }
        p.Save();
        UnloadAnyProject();
    }

    private static void UnloadAnyProject()
    {
        Microsoft.Build.Evaluation.ProjectCollection projcoll = Microsoft.Build.Evaluation.ProjectCollection.GlobalProjectCollection;

        foreach (Microsoft.Build.Evaluation.Project pr in projcoll.LoadedProjects)
        {
            Microsoft.Build.Evaluation.ProjectCollection mypcollection = pr.ProjectCollection;
            mypcollection.UnloadProject(pr);
        }
    }
  }
}

应该编译的目标项目:

using System;
namespace MyCSharp7
{
  class Program
  {
    static void Main(string[] args)
    {
        Console.WriteLine("truncate {0}", Truncate("Hello", 3));
    }

    public static string Truncate(string value, int length)
    {
        //csharp 6/7
        //comment out line below for succesfull compilation
        return value?.Substring(0, Math.Min(value.Length, length));

        // csharp<6
        string result = value;
        if (value != null) // Skip empty string check for elucidation
        {
            result = value.Substring(0, Math.Min(value.Length, length));
        }
        return result;
    }
  }
}
4

2 回答 2

0

我终于找到了解决方法。

在您的编译项目的引用中,不要使用 Microsoft.Build 和 Microsoft.Build.Framework 的标准 .net 程序集。让对 Microsoft.Build 和 Microsoft.Build.Framework 的引用指向随 Visual Studio 安装而安装的构建引擎中的相应 dll。

在 fi VS2017 的默认安装中,构建引擎位于:C:\Program Files (x86)\MSBuild\14.0\Bin\

因此,通过从那里选择 Microsoft.Build.dll 和 Microsoft.Build.Framework.dll 在构建的项目中添加引用

此解决方法不能解决上述问题。我认为问题是因为自从引入 C# 6 和 7 以来,.Net Microsoft Build 库从未被重新编程过

于 2017-04-06T21:19:04.323 回答
0

如果您安装MS Build2015(或从此处安装),您将15.0在磁盘上看到该文件夹​​,然后使用该exe文件,问题应该得到解决(对我有用)。

于 2017-04-07T20:12:20.337 回答