如何从C#调用MSBuild

是否有更好的方法从C#/ .NET调用MSBuild而不是shelling到msbuild.exe? 如果有,怎么样?

是的,添加对Microsoft.Build.Engine的引用并使用Engine类。

PS:注意参考正确的版本。 有2.0和3.5程序集,你必须确保每个人都得到正确的 。

对于特定于.NET 2.0的版本,您可以使用以下内容:

 Engine engine = new Engine(); engine.BinPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.System) + @"\..\Microsoft.NET\Framework\v2.0.50727"; FileLogger logger = new FileLogger(); logger.Parameters = @"logfile=C:\temp\test.msbuild.log"; engine.RegisterLogger(logger); string[] tasks = new string[] { "MyTask" }; BuildPropertyGroup props = new BuildPropertyGroup(); props.SetProperty("parm1","hello Build!"); try { // Call task MyTask with the parm1 property set bool success = engine.BuildProjectFile(@"C:\temp\test.msbuild",tasks,props); } catch (Exception ex) { // your error handler } finally { engine.UnregisterAllLoggers(); engine.UnloadAllProjects(); } 

如果您使用Microsoft.Build.Engine.Engine ,您将收到警告: This class has been deprecated. Please use Microsoft.Build.Evaluation.ProjectCollection from the Microsoft.Build assembly instead. This class has been deprecated. Please use Microsoft.Build.Evaluation.ProjectCollection from the Microsoft.Build assembly instead.

现在,从C#运行MSBuild的正确方法如下所示:

 public sealed class MsBuildRunner { public bool Run(FileInfo msbuildFile, string[] targets = null, IDictionary properties = null, LoggerVerbosity loggerVerbosity = LoggerVerbosity.Detailed) { if (!msbuildFile.Exists) throw new ArgumentException("msbuildFile does not exist"); if (targets == null) { targets = new string[] {}; } if (properties == null) { properties = new Dictionary(); } Console.Out.WriteLine("Running {0} targets: {1} properties: {2}, cwd: {3}", msbuildFile.FullName, string.Join(",", targets), string.Join(",", properties), Environment.CurrentDirectory); var project = new Project(msbuildFile.FullName, properties, "4.0"); return project.Build(targets, new ILogger[] { new ConsoleLogger(loggerVerbosity) }); } } 

如果您只需要MSBuild工具文件夹的路径,则可以使用Microsoft.Build.Utilities.Core程序ToolLocationHelper类 :

 var toolsetVersion = ToolLocationHelper.CurrentToolsVersion; var msbuildDir = ToolLocationHelper.GetPathToBuildTools(toolsetVersion); 

CurrentToolsVersion在ToolLocationHelper类中不可用,我在这里使用V.