Monday, January 13, 2014

How to build a solution using c# code in .NET 4.5 and retrieve the build result

Following is the code using which you can perform automated compilation of visual studio solutions through C#. First of all let’s retrieve the executing assembly path to write the output log of build activity performed using C#.
//retrieve assembly execution path
string assemblyExecutionPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
string logFilePath = assemblyExecutionPath.Remove(assemblyExecutionPath.LastIndexOf("\\") + 1) + "build.log";
Let’s create a collection to hold the output –
OutputHeaderRow = new List<string>();
OutputItemRow = new List<string>();
Let’s say the path of the solution to build using C# code is present in following variable - string artifactPath = @"C:\Kunal_AppDev\New folder\Test Data Solution\ MySolution.sln"
Following is the remaining complete code –

                    // Instantiate a new FileLogger to generate build log
                    FileLogger logger = new FileLogger(); 

                    // Set the logfile parameter to indicate the log destination
                    logger.Parameters = @"logfile=" + logFilePath; 

                    ProjectCollection pc = new ProjectCollection(); 

                    Dictionary<string, string> GlobalProperty = new Dictionary<string, string>();
                    GlobalProperty.Add("Configuration", "Debug");
                    GlobalProperty.Add("Platform", "Any CPU"); 

                    BuildRequestData buildRequest = new BuildRequestData(artifactPath, GlobalProperty, null, new string[] { "Build" }, null); 

                    //register file logger using BuildParameters
                    BuildParameters bp = new BuildParameters(pc);
                    bp.Loggers = new List<Microsoft.Build.Framework.ILogger> { logger }.AsEnumerable();

                    //build solution
                    BuildResult buildResult = BuildManager.DefaultBuildManager.Build(bp, buildRequest); 

                    //Unregister all loggers to close the log file               

                    //read lines from log file having project build output details
                    string[] solutionBuildOutputs = File.ReadAllLines(logFilePath); 

                    //write the result of solution build to html report
                    OutputHeaderRow.Add("Artifact;Build Result"); 

                    //split the contents of logger file to retrieve project build details
                    string[] splitter = { "__________________________________________________" };
                    string loggerOutput = File.ReadAllText(logFilePath);
                    string[] projectResults = loggerOutput.Split(splitter, StringSplitOptions.None);
                    foreach (string projectBuildDetails in projectResults)
                        if (projectBuildDetails.Contains("(default targets):"))
                            if (projectBuildDetails.Contains("Done building project \""))
                                //write the result of failed projects build to html report
                                string[] lines = projectBuildDetails.Split("\n".ToCharArray());
                                string buildFailedProjectName = lines.Where(x => x.Contains("Done building project \"")).FirstOrDefault();
                                buildFailedProjectName = buildFailedProjectName.Replace("Done building project ", string.Empty).Trim();
                                buildFailedProjectName = buildFailedProjectName.Replace("\"", string.Empty);
                                buildFailedProjectName = buildFailedProjectName.Replace(" -- FAILED.", string.Empty);
                                OutputItemRow.Add(buildFailedProjectName + ";FAILED");
                                //write the result of successfully built projects to html report
                                string[] lines = projectBuildDetails.Split("\n".ToCharArray());
                                string buildSuccededProjectName = lines.Where(x => x.Contains(" (default targets):")).FirstOrDefault().Replace("\" (default targets):", "");
                                string finalProjectName = buildSuccededProjectName.Substring(buildSuccededProjectName.LastIndexOf("\\") + 1);
                                OutputItemRow.Add(finalProjectName + ";SUCCEEDED");
                catch (Exception ex)
                    throw ex;
                    //delete log file
Following screenshot shows the build result output in debug mode contained in string collection. This you can write to file or show in grid and anything as per your requirement –

Hope this helps.
Happy Building!!


  1. Really helpful. Thank you. As a feedback, I recommend that you explain your code a little more. Specially how to detect failed projects and successfully build projects.

  2. Hi saeed, Thanks for the valuable feedback. I think I have already written the logic to detec failed and successful projects.OutputItemRow variable is aready showing this result as depicted in last screenshots. :)