使用条件过滤文件的MSBuild项目组

4
这似乎很简单,但我无法让它正常工作。我想要做的只是嵌入资源的筛选列表。我尝试了多种方法,但好像都行不通。这是我认为正确的解决方案:
<ItemGroup>
  <AllEmbeddedResources Include="@(EmbeddedResource)" Condition="$(FullPath.Contains('Change')"/>
</ItemGroup>

编辑...为了澄清,结果没有条件,列表中包含所有嵌入式资源;有条件时,组为空。

我已经在目标内部和外部尝试过这种情况,并尝试将完整列表放在一个组中,然后在另一个组中进行筛选。 我知道我只是误解了 msbuild 语法的一些基本部分,但似乎无法解决它。期待被展示出愚蠢错误!


$ 用于引用属性。如果你想要引用元数据,应该使用 %,因此一开始你应该使用 %(FullPath...。但我100%确定这已经被问过了,所以只需搜索一下即可。 - stijn
@stijn 我也是这么想的,但如果我使用这个语法 [Condition="%(FullPath).Contains('Change')"],我会得到错误信息 [error MSB4092: 在条件 "%(FullPath).Contains('Change')" 的第12个字符位置发现了意外的符号 "."。] 有类似的问题已经被问过了,但无论我怎么按照他们的例子去做,似乎都不够接近。我会编辑并包含我尝试过的链接... - Adam
@Adam,你需要在静态评估(项目全局)期间还是在目标内部执行此操作?在静态评估期间很难做到。 - Martin Ullrich
@MartinUllrich 的意图是将文件列表传递给任务,然后验证一些其他事情(如果有任何区别,则为内联任务)。 我已尝试在包含任务的目标外部以及任务之前的目标内部进行操作。 两者似乎都不起作用。 - Adam
2个回答

11

在目标内部,可以使用批处理语法来处理项目,并使用System.String.Copy方法以便能够调用字符串的实例函数:

<Target Name="ListAllEmbeddedResources">
  <ItemGroup>
    <AllEmbeddedResources Include="@(EmbeddedResource)" Condition="$([System.String]::Copy(%(FullPath)).Contains('Change'))" />
  </ItemGroup>
  <Message Importance="high" Text="AllEmbeddedResources: %(AllEmbeddedResources.Identity)" />
</Target>
请注意,此语法仅适用于目标(target),而不是静态评估(直接位于<Project>节点下方的item group)。

1
完美运行!谢谢!很高兴我不是傻瓜...但很失望它如此难以理解! - Adam

1
条件属性必须返回一个布尔值,并且它作用于itemgroup的每个元素。您可以使用%(Identity)访问每个元素。假设您有一个未过滤的itemgroup,称为UnfilteredItems,并且您想使用一些正则表达式模式将其过滤成一个名为MyFilteredItems的组。
<ItemGroup>
  <MyFilteredItems Include="@(UnfilteredItems)" Condition="$([System.Text.RegularExpressions.Regex]::Match(%(Identity),'.*\\bin\\.*').Success)"/>
</ItemGroup> 

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