Running MSBuild scripts programmatically

Published 01 May 07 11:39 AM | john 

I love msbuild.  Before it came along I was a big nant user, but now I'm an msbuild convert.  It's not perfect, but it sure is better than batch files.  It really, really needs embeddable code snippets, and a debugger but once it has those it will totally rock.  If you are writing a program that needs to run "scripts" you really ought to consider creating those scripts in msbuild. 

Now, while it's easy enough to simply launch msbuild.exe, it's also trivially easy to launch the msbuild engine in your current process space, either in the same or a different application domain.  Here's the code to do it:

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

void RunBuild(string projectFile, string logFile, string target, BuildPropertyGroup globalProperties)
{
  bool success = false;
  Engine engine = new Engine();

  engine.BinPath = RuntimeEnvironment.GetRuntimeDirectory();

  try
  {
    FileLogger fileLogger = new FileLogger();
                
    fileLogger.Parameters = String.Format("logfile={0}", logFile);
    fileLogger.Verbosity = LoggerVerbosity.Diagnostic;
                
    TraceLogger traceLogger = new TraceLogger();
                
    traceLogger.Verbosity = LoggerVerbosity.Normal;

    engine.RegisterLogger(fileLogger);
    engine.RegisterLogger(traceLogger);

    success = engine.BuildProjectFile(projectFile, new string[] { target }, globalProperties);
  }
  finally
  {
    engine.UnregisterAllLoggers();
  }

  return success;
}

In the sample I am adding two loggers. The FileLogger is the default logger that MSBuild uses. The TraceLogger is one that I wrote that outputs to the TraceListener collection for unit tests, debugging, etc..  The key step is to unregister the loggers in a finally statement.  Unregistering flushes the loggers, so if you don't do it you get partial output. The globalProperties are properties that you want set in the script;  normally you would specify /p on the command line to set these.  Use the SetProperty method to define the properties in the collection.

Filed under: , , ,

Comments

# The Director of Random Technologies said on July 23, 2007 4:01 PM:

While I haven't been posting much here, I have been posting pretty regularly over on my main development

# Noticias externas said on July 23, 2007 5:02 PM:

While I haven't been posting much here, I have been posting pretty regularly over on my main development

Anonymous comments are disabled