How to call MSBuild from C#

后端 未结 5 1928
庸人自扰
庸人自扰 2020-12-24 12:46

Is there a better way to call MSBuild from C#/.NET than shelling out to the msbuild.exe? If yes, how?

相关标签:
5条回答
  • 2020-12-24 13:33

    If all you want is the path to the MSBuild tools folder, you can use the ToolLocationHelper class from the Microsoft.Build.Utilities.Core assembly:

    var toolsetVersion = ToolLocationHelper.CurrentToolsVersion;
    var msbuildDir = ToolLocationHelper.GetPathToBuildTools(toolsetVersion);
    
    0 讨论(0)
  • 2020-12-24 13:35

    For a .NET 2.0-specific version, you can use the following:

    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();
    }
    
    0 讨论(0)
  • 2020-12-24 13:39

    If you use Microsoft.Build.Engine.Engine, you'll get a warning: This class has been deprecated. Please use Microsoft.Build.Evaluation.ProjectCollection from the Microsoft.Build assembly instead.

    Now, the proper way to run MSBuild from C# looks like this:

    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) });
        }
    
    }
    
    0 讨论(0)
  • 2020-12-24 13:46

    Yes, add a reference to Microsoft.Build.Engine and use the Engine class.

    PS: Take care to reference the right version. There are 2.0 and 3.5 assemblies and you'll have to make sure that everyone gets the right one.

    0 讨论(0)
  • 2020-12-24 13:49

    CurrentToolsVersion is not available in ToolLocationHelper class, I am here using V

    0 讨论(0)
提交回复
热议问题