【发布时间】:2009-02-11 12:21:14
【问题描述】:
有没有更好的方法从 C#/.NET 调用 MSBuild,而不是使用 msbuild.exe?如果是,怎么做?
【问题讨论】:
-
相关问题(但使用 Powershell 而不是原始 C#) - stackoverflow.com/questions/472038/…
有没有更好的方法从 C#/.NET 调用 MSBuild,而不是使用 msbuild.exe?如果是,怎么做?
【问题讨论】:
是的,添加对Microsoft.Build.Engine 的引用并使用Engine 类。
PS:注意参考正确的版本。有 2.0 和 3.5 程序集,您必须make sure that everyone gets the right one。
【讨论】:
对于特定于 .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.
现在,从 C# 运行 MSBuild 的正确方法如下所示:
public sealed class MsBuildRunner
{
public bool Run(FileInfo msbuildFile, string[] targets = null, IDictionary<string, string> 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<string, string>();
}
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 class:
var toolsetVersion = ToolLocationHelper.CurrentToolsVersion;
var msbuildDir = ToolLocationHelper.GetPathToBuildTools(toolsetVersion);
【讨论】:
Microsoft.Build.Utilities.Core 的ToolLocationHelper,而不是来自Microsoft.Build.Utilities 的那个。
CurrentToolsVersion 在 ToolLocationHelper 类中不可用,我在这里使用 V
【讨论】: