给定一个构建文件(.csproj或msbuild.xml或其他),我想运行一个msbuild命令,列出所有可用的定义目标。
该功能是否存在?
我知道我可以在构建文件上进行Xpath搜索,但是找不到包含文件中定义的目标。
答案 0 :(得分:21)
您可以像这样编写自定义的msbuild任务:
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;
}
}
}
你会像那样使用:
<Target Name="TestGetAllTargets">
<GetAllTargets ProjectFile="$(MSBuildProjectFile)">
<Output ItemName="TargetItems" TaskParameter="Targets"/>
</GetAllTargets>
<Message Text="Name: %(TargetItems.Identity) Input: %(TargetItems.Input) --> Output: %(TargetItems.Output)"/>
</Target>
使用MSBuild 4,你可以使用新的闪亮的东西:内联任务。内联任务允许您直接在msbuild文件中定义行为。
<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>
答案 1 :(得分:3)
从Visual Studio 16.6预览版1开始,这是在MSBuild中实现的。
用法示例:
msbuild myProject.proj -targets
这应该与Visual Studio 16.6预览版1一起使用(在将来的某个时候)。
(来源:https://github.com/microsoft/msbuild/pull/5032#issuecomment-587901124)
文档:
-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