过滤现有项目组,使其仅包含符合某些条件的文件

Posted

技术标签:

【中文标题】过滤现有项目组,使其仅包含符合某些条件的文件【英文标题】:Filter an existing itemgroup so it only includes files that match some condition 【发布时间】:2012-08-26 17:10:09 【问题描述】:

如何根据特定条件(例如文件扩展名或项目的元数据)过滤现有的 ItemGroup?

在本例中,我将使用文件扩展名。我正在尝试过滤 VS 定义的“无”ItemGroup,以便我的目标可以对给定扩展名的所有文件进行操作。

例如,可以定义以下内容:

<ItemGroup>
    <None Include="..\file1.ext" />
    <None Include="..\file2.ext" />
    <None Include="..\file.ext2" />
    <None Include="..\file.ext3" />
    <None Include="..\file.ext4" />
</ItemGroup>

我想过滤上面的“无”ItemGroup,使其仅包含ext 扩展名。请注意,我确实不想指定要排除的所有扩展,因为它们会因项目而异,而且我正在尝试使我的目标无需修改即可重复使用。

我尝试在目标中添加Condition

<Target Name="Test">
    <ItemGroup>
        <Filtered
            Include="@(None)"
            Condition="'%(Extension)' == 'ext'"
            />
    </ItemGroup>
    <Message Text="None: '%(None.Identity)'"/>
    <Message Text="Filtered: '%(Filtered.Identity)'"/>
</Target>

但遗憾的是,它不起作用。我得到以下输出:

Test:
  None: '..\file1.ext'
  None: '..\file2.ext'
  None: '..\file.ext2'
  None: '..\file.ext3'
  None: '..\file.ext4'
  Filtered: ''

【问题讨论】:

我相信 %(Extension) 需要是 '.ext' 我的意思是它实际上需要是'.ext',就像第一个字符用点一样,这样就可以了。 【参考方案1】:
<ItemGroup>
  <Filtered Include="@(None)" Condition="'%(Extension)' == '.ext'" />
</ItemGroup>

【讨论】:

这对我不起作用。 error MSB4190: The reference to the built-in metadata "Extension" at posi tion 1 is not allowed in this condition "'%(Extension)' == '.ext'". 我支持&lt;Target&gt; 注释,并补充一点:在普通编程语言中,您会期望&lt;Filtered&gt; ItemGroup 的范围为包含在其中的&lt;Target&gt;。不是这样MSBuild:如果您在目标中定义 &lt;Filtered&gt;,它将可用于其他目标,因此如果您需要在另一个目标中使用 ItemGroup,只需将新 &lt;Target&gt;BeforeTargets 属性设置为您所在的目标需要 ItemGroup。 @MarcinWisnicki 确保在您想要访问众所周知的项目元数据时将 ItemGroup 放入目标中。否则你会得到那个错误。【参考方案2】:

对于高级过滤,我建议使用来自MSBuild Community Tasks 的RegexMatch

在本例中,我们将过滤版本号

    <RegexMatch Input="@(Items)" Expression="\d+\.\d+\.\d+.\d+">
        <Output ItemName ="ItemsContainingVersion" TaskParameter="Output" />
    </RegexMatch>

通过 Nuget 安装 MSBuild 社区任务:PM> Install-Package MSBuildTasks 或下载它here

然后将其导入您的 MSBuild 脚本:

<PropertyGroup>
    <MSBuildCommunityTasksPath>..\.build\</MSBuildCommunityTasksPath>
</PropertyGroup>
<Import Project="$(MSBuildCommunityTasksPath)MsBuild.Community.Tasks.Targets" />

【讨论】:

以上是关于过滤现有项目组,使其仅包含符合某些条件的文件的主要内容,如果未能解决你的问题,请参考以下文章

永久排除某些跟踪文件

我可以在 Visual Studio 2003 中添加文件并使其指向另一个项目中的现有文件吗?

让useEffect监视条件并使其仅触发一次

LINQ:根据某些条件过滤项目列表,并按条件执行某些操作

在 GWT 中,如何调整菜单项的大小以使其仅限于菜单栏

如何处理弹性beantalk部署,使其仅上传更改的文件