Is there a way to list all the build targets available in a build file?

后端 未结 2 378
梦如初夏
梦如初夏 2021-02-05 09:23

Given a build file (.csproj or msbuild.xml or whatever), I\'d like to run a msbuild command that lists all the available, defined targets.

Does that function exist?

相关标签:
2条回答
  • 2021-02-05 10:05

    Using MSBuild 2.0/3.5 : Custom Task

    You could write a custom msbuild task like this :

    using System;
    using System.Collections.Generic;
    using Microsoft.Build.BuildEngine;
    using Microsoft.Build.Framework;
    using Microsoft.Build.Utilities;
    
    namespace MSBuildTasks
    {
      public class GetAllTargets : Task
      {
        [Required]
        public String ProjectFile { get; set; }
    
        [Output]
        public ITaskItem[] Targets { get; set; }
    
        public override bool Execute()
        {
          var project = new Project(BuildEngine as Engine);
          project.Load(ProjectFile);
    
          var taskItems = new List<ITaskItem>(project.Targets.Count);
          foreach (Target target in project.Targets)
          {
            var metadata = new Dictionary<string, string>
                            {
                              {"Condition", target.Condition},
                              {"Inputs", target.Inputs},
                              {"Outputs", target.Outputs},
                              {"DependsOnTargets", target.DependsOnTargets}
                            };
            taskItems.Add(new TaskItem(target.Name, metadata));
          }
    
          Targets = taskItems.ToArray();
    
          return true;
        }
      }
    }    
    

    That you'll use like that:

    <Target Name="TestGetAllTargets">
      <GetAllTargets ProjectFile="$(MSBuildProjectFile)">
        <Output ItemName="TargetItems" TaskParameter="Targets"/>
      </GetAllTargets>
    
      <Message Text="Name: %(TargetItems.Identity) Input: %(TargetItems.Input) --> Output: %(TargetItems.Output)"/>
    </Target>
    

    Using MSBuild 4.0 : Inline task

    With MSBuild 4 you could use the new shiny thing : the inline task. Inline task allows you to define the behavior directly in msbuild file.

    <UsingTask TaskName="GetAllTargets"
               TaskFactory="CodeTaskFactory"
               AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
      <ParameterGroup>
        <ProjectFile ParameterType="System.String" Required="true"/>
        <TargetsOut ParameterType="Microsoft.Build.Framework.ITaskItem[]" Output="true"/>
      </ParameterGroup>
      <Task>
        <Reference Include="System.Xml"/>
        <Reference Include="Microsoft.Build"/>
        <Reference Include="Microsoft.Build.Framework"/>
        <Using Namespace="Microsoft.Build.Evaluation"/>
        <Using Namespace="Microsoft.Build.Execution"/>
        <Using Namespace="Microsoft.Build.Utilities"/>
        <Using Namespace="Microsoft.Build.Framework"/>
        <Code Type="Fragment" Language="cs">
          <![CDATA[
            var project = new Project(ProjectFile);
    
            var taskItems = new List<ITaskItem>(project.Targets.Count);
            foreach (KeyValuePair<string, ProjectTargetInstance> kvp in project.Targets)
            {
              var target = kvp.Value;
              var metadata = new Dictionary<string, string>
                              {
                                {"Condition", target.Condition},
                                {"Inputs", target.Inputs},
                                {"Outputs", target.Outputs},
                                {"DependsOnTargets", target.DependsOnTargets}
                              };
              taskItems.Add(new TaskItem(kvp.Key, metadata));
            }
    
            TargetsOut = taskItems.ToArray();
          ]]>
        </Code>
      </Task>
    </UsingTask>
    
    <Target Name="Test">
      <GetAllTargets ProjectFile="$(MSBuildProjectFile)">
        <Output ItemName="TargetItems" TaskParameter="TargetsOut"/>  
      </GetAllTargets>
    
      <Message Text="%(TargetItems.Identity)"/>
    </Target>
    
    0 讨论(0)
  • 2021-02-05 10:17

    Starting with Visual Studio 16.6 preview 1, this is implemented in MSBuild.

    Example usage: msbuild myProject.proj -targets

    This should go out with Visual Studio 16.6 preview 1 (at some point in the future).

    (source: https://github.com/microsoft/msbuild/pull/5032#issuecomment-587901124)

    Documentation:

    -targets[:file]
                     Prints a list of available targets without executing the
                     actual build process. By default the output is written to
                     the console window. If the path to an output file
                     is provided that will be used instead.
                     (Short form: -ts)
                     Example:
                       -ts:out.txt
    
    0 讨论(0)
提交回复
热议问题