由于某种需求, 需要实现一种工具, 可以批量编译一定数量的工程文件, 有些人可能会说, 直接使用批量脚本, 在里面使用MSBuild来实现, 这是一个实现方法, 但是总觉得这种实现不是很爽! 在使用了TFS Build的功能之后, 觉得这种批量build的功能很不错, 所以想找个方法, 能不能自己也写个工具, 模拟TFS build, 自动实现批量的Build呢! 经过一番研究, 找到了一个方法, 看下面的 Demo Code:
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Text;
5:
6: using Microsoft.Build.Framework;
7: using Microsoft.Build.Evaluation;
8: using Microsoft.Build.Utilities;
9: using Microsoft.Build.Execution;
10: using System.Collections.ObjectModel;
11:
12: namespace MSBuildDemo
13: {
14: /// <summary>
15: /// Class defines the functionalies of build a project or solution.
16: /// </summary>
17: public static class CustomerBuildManager
18: {
19: /// <summary>
20: /// Method to build a project.
21: /// </summary>
22: /// <param name="projectFilePath">The project file path.</param>
23: /// <param name="buildResultFilePath">The log file path to show the build result.</param>
24: /// <returns>If build success, return <c>true</c>, otherwise, return <c>false</c>.</returns>
25: public static bool BuildProject(string projectFilePath, string buildResultFilePath)
26: {
27: if (string.IsNullOrEmpty(projectFilePath) || string.IsNullOrEmpty(buildResultFilePath))
28: {
29: throw new ArgumentNullException("Parameter should not be empty or null!");
30: }
31:
32: bool isSuccess = false;
33: using (ProjectCollection projectCollection = new ProjectCollection())
34: {
35: ILogger logger = new Microsoft.Build.Logging.FileLogger() { Parameters = buildResultFilePath };
36:
37: projectCollection.RegisterLogger(logger);
38: Project project = projectCollection.LoadProject(projectFilePath);
39:
40: try
41: {
42: isSuccess = project.Build();
43: }
44: finally
45: {
46: logger.Shutdown();
47: }
48: }
49:
50: return isSuccess;
51: }
52:
53: /// <summary>
54: /// Method to build a solution.
55: /// </summary>
56: /// <param name="solutionFilePath">The solution file path.</param>
57: /// <param name="buildResultFilePath">The build result file path.</param>
58: /// <returns>If build success, return <c>true</c>, otherwise, return <c>false</c>.</returns>
59: public static bool BuildSolution(string solutionFilePath, string buildResultFilePath)
60: {
61: if (string.IsNullOrEmpty(solutionFilePath) || string.IsNullOrEmpty(buildResultFilePath))
62: {
63: throw new ArgumentNullException("Parameter should not be empty or null!");
64: }
65:
66: bool isSuccess = false;
67: using (ProjectCollection projectCollection = new ProjectCollection())
68: {
69: Dictionary<string, string> globalProperty = new Dictionary<string, string>();
70: ILogger logger = new Microsoft.Build.Logging.FileLogger() { Parameters = buildResultFilePath };
71:
72: globalProperty.Add("Configuration", "Debug");
73: globalProperty.Add("Platform", "x86");
74:
75: BuildRequestData buidlRequest = new BuildRequestData(
76: solutionFilePath,
77: globalProperty,
78: null,
79: new string[] { "Build" },
80: null);
81:
82: BuildResult buildResult = null;
83: try
84: {
85: buildResult = BuildManager.DefaultBuildManager.Build(
86: new BuildParameters(projectCollection) { Loggers = new Collection<ILogger> { logger } },
87: buidlRequest);
88: }
89: finally
90: {
91: logger.Shutdown();
92: }
93:
94: isSuccess = buildResult != null ? buildResult.OverallResult == BuildResultCode.Success : false;
95: }
96:
97: return isSuccess;
98: }
99: }
100: }
其实代码很简单, 就是定义一个ProjectCollection, 使用这个ProjectCollection去帮助我们Build我们的project或者Solution. 具体的调用参数可以参考MSDN. 下面是调用的Demo Code:
1: using System;
2: using System.Collections.Generic;
3: using System.Linq;
4: using System.Text;
5:
6: namespace MSBuildDemo
7: {
8: class Program
9: {
10: [STAThread]
11: static void Main(string[] args)
12: {
13: // Build Project.
14: string projectFilePath = @"C:\Users\Administrator\Documents\Visual Studio 2010\Projects\WCFDemo\WCFDemo\WCFDemo.csproj";
15: string projectBuildResultFilePath = @"logfile=C:\projectLog.txt";
16: bool isBuildProjectSuccess = CustomerBuildManager.BuildProject(projectFilePath, projectBuildResultFilePath);
17:
18: if (isBuildProjectSuccess)
19: {
20: Console.WriteLine("Build Porject Success!");
21: }
22: else
23: {
24: Console.WriteLine("Build Porject Failed!");
25: }
26:
27: string solutionFilePath = @"C:\Users\Administrator\Documents\Visual Studio 2010\Projects\WCFDemo\WCFDemo.sln";
28: string solutionBuildResultFilePath = @"logfile=C:\solutionLog.txt";
29: bool isBuildSolutionSuccess = CustomerBuildManager.BuildSolution(solutionFilePath, solutionBuildResultFilePath);
30:
31: if (isBuildSolutionSuccess)
32: {
33: Console.WriteLine("Build Solution Success!");
34: }
35: else
36: {
37: Console.WriteLine("Build Solution Failed!");
38: }
39:
40: Console.ReadLine();
41: }
42: }
43: }
同时还会在你设置的log目录下面出现对应的build log文件!
通过这种方法,我们可以很轻松的实现在code里面去编译我们的工程文件, 特别是当我们的项目工程非常多的时候,可以借助这个功能去实现一个小工具, 简简单单几行代码, 就可以简化我们日常的工作!