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?
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>
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>
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