Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I build a solution programmatically in C#?

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;

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


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

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

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

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


If you need to trigger the build from Visual Studio extension code, you must consider the limitations imposed by IVsBuildManagerAccessor interface - see the General Notes, including new IVsBuildManagerAccessor.docx from Managed Package Framework for Projects. Its fork is also available at GitHub.

In Visual Studio 2010 with MSBuild 4.0, there are new interactions between the Solution Build Manager and MSBuild which impact project systems utilizing these services. MSBuild 4.0 contains a new component called the Build Manager (not to be confused with the Solution Build Manager which is a VS component) which controls the submission of build requests. This became necessary as Visual Studio 2010 now allows parallel builds to occur (notably native projects) and access to shared resources such as the CPU needed to be mediated. For project systems which previously simply called Project.Build() to invoke a build several changes must be made. The project system now must:

  1. Ask for the SVsBuildManagerAccessor service using the IServiceProvider interface. This should be done soon after the project system is loaded, well before any builds might occur.
  2. Notify the system if you need the UI thread
  3. Notify the system if you are doing a design-time build.
  4. Register its loggers using the Build Manager Accessor.
  5. Submit build requests directly to the MSBuild Build Manager, rather than invoking a method on the Project.