4

I am using the MSBUILD API to build solutions using a service.

eg

var pc = new ProjectCollection();
var buildProperties = new Dictionary<string, string>
{
   {"Configuration", "Release"},
   {"Platform", "Any CPU"},
   {"OutputPath", _outputPath}
};

var buildParameters = new BuildParameters(pc);

var buildRequest = new BuildRequestData(_buildFile, buildProperties, null, new[] { "Clean", "Rebuild" }, null);            

var buildResult = BuildManager.DefaultBuildManager.Build(buildParameters, buildRequest);

What I want to be able to do, is pass in a list of excluded project types or extensions. To start with I would like to exclude:

  • Database projects
  • WinRT projects
  • generic MSBUILD files (no project type GUID).

Are there any ways to solve this by passing in some parameters to the MSBUILD manager?

Doug
  • 6,460
  • 5
  • 59
  • 83

1 Answers1

4

This isn't quite what you're after, but I just happened to be mucking around with the msbuild API during the old day-job, and figured this code might be useful:

var basePath = "path-to-where-source-is";
var outputDir = "path-to-output";

// Setup some properties that'll apply to all projs
var pc = Microsoft.Build.Evaluation.ProjectCollection.GlobalProjectCollection;
pc.SetGlobalProperty("Configuration", "Debug");
pc.SetGlobalProperty("Platform", "Any CPU");
pc.SetGlobalProperty("OutDir", outputDir);

// Generate the metaproject that represents a given solution file
var slnProjText = SolutionWrapperProject.Generate(
    Path.Combine(basePath, "NAME-OF-SOLUTION-FILE.sln"), 
    "4.0", 
    null);

// It's now a nice (well, ugly) XML blob, so read it in
using(var srdr = new StringReader(slnProjText))
using(var xrdr = XmlReader.Create(srdr))
{
    // Load the meta-project into the project collection        
    var slnProj = pc.LoadProject(xrdr, "4.0");

    // Slice and dice the projects in solution with LINQ to
    // get a nice subset to work with
    var solutionProjects = 
        from buildLevel in Enumerable.Range(0, 10)
        let buildLevelType = "BuildLevel" + buildLevel
        let buildLevelItems = slnProj.GetItems(buildLevelType)
        from buildLevelItem in buildLevelItems
        let include = buildLevelItem.EvaluatedInclude
        where !include.Contains("Some thing I don't want to build")
        select new 
        { 
            Include=include, 
            Project = pc.LoadProject(Path.Combine(basePath, include))
        };

    // For each of them, build em!
    foreach (var projectPair in solutionProjects)
    {
        var project = projectPair.Project;
        var include = projectPair.Include;
        var outputPath = outputDir;
        project.SetProperty("OutputPath", outputPath);
        Console.WriteLine("Building project:" + project.DirectoryPath);
        var buildOk = project.Build("Build");
        if(buildOk)
        {
            Console.WriteLine("Project build success!");
        } 
        else
        {
            throw new Exception("Build failed");
        }
    }
}
JerKimball
  • 16,584
  • 3
  • 43
  • 55
  • 1
    Yessir - the solution wrapper handles the transformation from solution syntax (which is a legacy-laden mess) to msbuild project syntax, which is far nicer (and proper xml) – JerKimball Feb 28 '13 at 00:53