How do I build a solution programmatically in C#?

How do I build a C# solution programmatically?

I should be able to pass the path of a solution and get the output messages (or just build the solution). How do I achieve this in C#?

I need this because we are building a single solution for our projects when it now gets everything from SVN and also builds it. Next would be deploying it all in one click.


Solution 1:

See .NET 4.0 MSBuild API introduction for an example using the .NET 4.0 MSBuild API:

List<ILogger> loggers = new List<ILogger>();
loggers.Add(new ConsoleLogger());
var projectCollection = new ProjectCollection();
projectCollection.RegisterLoggers(loggers);
var project = projectCollection.LoadProject(buildFileUri); // Needs a reference to System.Xml
try
{
    project.Build();
}
finally
{
    projectCollection.UnregisterAllLoggers();
}

A simpler example:

var project = new Project(buildFileUri, null, "4.0");
var ok = project.Build(); // Or project.Build(targets, loggers)
return ok;

Remember to use the .NET 4 Profile (not the Client profile).

Add the following references: System.XML, Microsoft.Build, Microsoft.Build.Framework, and optionally Microsoft.Build.Utilities.v4.0.

Also look at Stack Overflow question Running MSBuild programmatically.

To build a solution, do the following:

var props = new Dictionary<string, string>();
props["Configuration"] = "Release";
var request = new BuildRequestData(buildFileUri, props, null, new string[] { "Build" }, null);
var parms = new BuildParameters();
// parms.Loggers = ...;

var result = BuildManager.DefaultBuildManager.Build(parms, request);
return result.OverallResult == BuildResultCode.Success;

Solution 2:

Most of the answers are providing ways to do it by calling external commands, but there is an API, Microsoft.Build.Framework, to build via C#.


Code from blog post:

using Microsoft.Build.BuildEngine;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

public class SolutionBuilder
{
    BasicFileLogger b;
    public SolutionBuilder() { }

    [STAThread]
    public string Compile(string solution_name,string logfile)
    {
        b = new BasicFileLogger();
        b.Parameters = logfile;
        b.register();
        Microsoft.Build.BuildEngine.Engine.GlobalEngine.BuildEnabled = true;
        Project p = new Project (Microsoft.Build.BuildEngine.Engine.GlobalEngine);
        p.BuildEnabled = true;
        p.Load(solution_name);
        p.Build();
        string output = b.getLogoutput();
        output += “nt” + b.Warningcount + ” Warnings. “;
        output += “nt” + b.Errorcount + ” Errors. “;
        b.Shutdown();
        return output;
    }
}
// The above class is used and compilation is initiated by the following code,
static void Main(string[] args)
{
    SolutionBuilder builder = new SolutionBuilder();
    string output = builder.Compile(@”G:CodesTestingTesting2web1.sln”, @”G:CodesTestingTesting2build_log.txt”);
    Console.WriteLine(output);
    Console.ReadKey();
}

Note the code in that blog post works, but it is a little dated. The

Microsoft.Build.BuildEngine

has been broken up into some pieces.

Microsoft.Build.Construction

Microsoft.Build.Evaluation

Microsoft.Build.Execution

Solution 3:

// Fix to the path of your MSBuild executable
var pathToMsBuild = "C:\\Windows\\DotNet\\Framework\\msbuild.exe";

Process.Start(pathToMsBuild + " " + pathToSolution);

Solution 4:

You can create a .proj file:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <!-- Common -->
    <Solution Include="Common\Util\Util.sln"/>
    <Solution Include="Common\EventScheduler\EventSchedulerSolution\EventSchedulerSolution.sln"/>
    <!-- Server -->
    <Solution Include="Server\DataLayer\DataTransferObjects\SharedModel\SharedModel.sln"/>
    <Solution Include="Server\DataLayer\DataTier\ESPDAL.sln"/>
    <!-- Internal Tools -->
    <Solution Include="InternalTools\ServerSchemaUtility\ServerSchemaUtility.sln"/>
  </ItemGroup>
  <Target Name="Rebuild">
    <MSBuild Projects="@(Solution)" Targets="Rebuild" Properties="Configuration=Release"/>
  </Target>
</Project>

And then call msbuild.exe using the project file as an argument. Below is a batch file example. From C#, you could call Process.Start as indicated by other posters.

"C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe" BuildSolutions.proj

pause

Solution 5:

You can try blog post Take control of MSBuild using MSBuild API.