如何从MsBuild项目中获取最后一个项目?

5
在我的构建脚本中,我有一段代码:
<CreateItem Include="src\packages\**\nunit-console.exe">
  <Output TaskParameter="Include" ItemName="NUnitRunners"/>
</CreateItem>

实际上,它在我的软件包文件夹中找到了所有的 nunit-console.exe,让它像这样被使用:

<Exec Command="&quot;@(NUnitRunners)&quot; ..." />

当只有一个nunit-console.exe时,它可以工作,但如果存在多个,则显然只是将路径连接起来。

  1. 有没有办法从项集合(在我的情况下为NUnitRunners)中获取最后一项?
  2. 还有其他技巧可以获取packages文件夹中最新的nunit-console.exe的路径吗?
3个回答

3
这可能有点hacky,但您可以使用批处理来提取最后一项,只需将%(Items.Identity)分配给属性即可。
提取第一个项目有点棘手,您必须通过创建新项目来反转原始项目的顺序<Reversed Include = "@(Items->Reverse())" />。 然后将%(Reversed.Identity)分配给属性。
我不确定这是否会破坏程序,但即使启用并行构建,它在我的测试中看起来很好。
在此处查看示例:https://gist.github.com/shadow-cs/cb5499b010bdacd1f778be29daf7f04c

2

1
我正在尝试解决完全相同的问题。我编写了一个内联任务来解决这个问题:
<UsingTask TaskName="GetFirstItem" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll">
  <ParameterGroup>
    <Items ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
    <FirstItem ParameterType="System.String" Output="true" Required="false" />
  </ParameterGroup>
  <Task>
    <Using Namespace="System.Linq"/>
    <Code Type="Fragment" Language="cs">FirstItem = Items.First().ItemSpec;</Code>
  </Task>
</UsingTask>

这里有一个例子:https://gist.github.com/Serivy/74fff320c93176e6ca7f76e1cc139367

但最终我不想增加额外的负担,如果数量过多或不足,则会显示错误消息。

<Error Condition="@(NUnitRunners->Count()) != 1" Text="@(NUnitRunners->Count()) nunit runners found." />

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接