Compilation 用c#版本6和7代码以编程方式构建c#项目会导致编译错误

Compilation 用c#版本6和7代码以编程方式构建c#项目会导致编译错误,compilation,msbuild,c#-6.0,programmatically,c#-7.0,Compilation,Msbuild,C# 6.0,Programmatically,C# 7.0,我希望通过使用以编程方式编译目标项目 Microsoft.Build.Evaluation.Project.Build() 如果我需要编译的目标项目包含安全导航操作符(?。操作符)等C#6.0功能,则它会在这些代码行上准确地给出错误。 如果我在目标项目中删除这些代码行,它就可以编译 有人知道如何以编程方式编译C#6.0和7.0风格的代码吗? 在构建我的运行时版本的项目中,buildMicrosoft.build.dll是v4.0.30319,.Net框架版本是4.6.2 我添加了两个简单的

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

Microsoft.Build.Evaluation.Project.Build()  
如果我需要编译的目标项目包含安全导航操作符(
?。
操作符)等
C#
6.0功能,则它会在这些代码行上准确地给出错误。
如果我在目标项目中删除这些代码行,它就可以编译

有人知道如何以编程方式编译
C#
6.0和7.0风格的代码吗?
在构建我的运行时版本的项目中,build
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);
        }
    }
  }
}
应编制的targetproject:

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;
    }
  }
}
使用系统;
名称空间MyCSharp7
{
班级计划
{
静态void Main(字符串[]参数)
{
WriteLine(“truncate{0}”,truncate(“Hello”,3));
}
公共静态字符串截断(字符串值,整数长度)
{
//csharp 6/7
//注释掉下面的行以成功编译
返回值?.Substring(0,数学最小值(value.Length,Length));

//csharp我终于找到了解决办法

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

在f.i.VS2017的默认安装中,建筑引擎位于: C:\ProgramFiles(x86)\MSBuild\14.0\Bin\

因此,通过从中选取Microsoft.Build.dll和Microsoft.Build.Framework.dll,在生成的项目中添加引用


此解决方法无法解决上述问题。我认为问题的原因是自从引入C#6和C#7以来,如果您安装(或从安装)的话,.Net Microsoft Build库从未重新编程过,您将在磁盘上看到
15.0
文件夹,使用该
exe
-文件后,问题应得到解决(为我解决)

如果在7中不存在,那么很有可能有一个很好的理由。考虑一下为什么它不再是它不再是关于不再存在的特征,而是关于在像C?6这样的版本中新添加的特征。操作员。您是否尝试过使用NuGet的Microsoft.Build
?我尝试过。它变得越来越糟糕。我安装了15.1.548。现在加载项目文件Project p=new Project(项目文件)时出错;MSB0001:内部MSBuild错误:Microsoft.Build.Utilities.ToolLocationHelper的类型信息在白名单缓存中显示为Microsoft.Build.Utilities.ToolLocationHelper,Microsoft.Build.Utilities.Core,版本=15.1.0.0,区域性=neutral,PublicKeyToken=b03f5f7f11d50a3a,但无法加载该类型。意外null@WMAtm谢谢很遗憾,我不会检查此解决方案,因为上面提到的解决方案正在运行,并且使用您的解决方案,我被迫在仅安装了VS2017的系统中安装额外的VS2015部件。为了防止类似的问题,请参见此处,了解“自动化”的可能方法对随Visual Studio一起安装的MSBuild组件的引用。