2

I want to compile a target project programmatically by using

Microsoft.Build.Evaluation.Project.Build()  

If my target project that needs to be compiled contains C# 6.0 features like the safe navigation operator (?. Operator) it gives errors exactly on these lines of code.
If I remove these lines of code in my target project it compiles fine.

Does anyone have any idea how to compile C# 6.0 and 7.0 style code programmatically?
In the project that builds my runtime version of the build Microsoft.Build.dll is v4.0.30319 and the .Net framework version is 4.6.2.

I added two simple projects. The first console project is the code that compiles. The second console project is the target project to be compiled. By commenting out line 15, the compilation successful, otherwise the logfile shows errors on that line.

The project that compiles

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);
        }
    }
  }
}

The targetproject that should be compiled:

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
  • if it doesn't exist in 7.0, there is a good chance there is a good reason for it. Consider reading up on why it is no longer there Commented Mar 30, 2017 at 11:40
  • It's not about features that don't exist anymore, it's about features that are newly added in the versions c# 6.0 like the ?. Operator and the nameof() operator. Commented Mar 30, 2017 at 12:34
  • 2
    Have you tried using Microsoft.Build from NuGet? Commented Mar 30, 2017 at 12:44
  • I tried it. it got from bad to worse. I installed 15.1.548 Now I get an error when loading the projectfile Project p = new Project(projectfile); MSB0001: Internal MSBuild Error: Type information for Microsoft.Build.Utilities.ToolLocationHelper was present in the whitelist cache as Microsoft.Build.Utilities.ToolLocationHelper, Microsoft.Build.Utilities.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a but the type could not be loaded. unexpectedly null Commented Mar 31, 2017 at 10:20

2 Answers 2

0

I finally found a workaround.

In the references of your compiling project do not use the standard .net assemblies of Microsoft.Build and Microsoft.Build.Framework. Let the references to Microsoft.Build and Microsoft.Build.Framework point to the corresponding dll's in the building engine that are installed with the installation of Visual Studio instead.

In a default installation of f.i. VS2017 the building engine is located in : C:\Program Files (x86)\MSBuild\14.0\Bin\

so add the references in the project that builds by picking Microsoft.Build.dll and the Microsoft.Build.Framework.dll from there

This workaround doesn't solve the problem mentioned above. I think the problem is caused that the .Net Microsoft Build libraries never have been reprogrammed since the introduction of C# 6 and 7

Sign up to request clarification or add additional context in comments.

1 Comment

See here stackoverflow.com/a/49992566/253938 for a possible way to "automate" the referencing of the MSBuild components that are installed with Visual Studio.
0

If you install MS Build 2015 (or from here), you'll see the 15.0 folder on your disk, after that use that exe-file, problem should be resolved (worked for me).

1 Comment

@WMAtm Thanks for your reply. Unfortunately I won't check this solution because the workaround mentioned above is working and with your solution I am forced installing extra VS2015 parts in a system with only a VS2017 installation. Just preventing trouble like this link

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.