规范化MSBuild中的项列表

规范化MSBuild中的项列表,msbuild,unique,distinct,normalize,Msbuild,Unique,Distinct,Normalize,我正在尝试获取项目根目录下所有单元测试程序集的列表。我可以这样做: <CreateItem Include="**\bin\**\*.UnitTest.*.dll"> <Output TaskParameter="Include" ItemName="Items"/> </CreateItem> 但是,这会多次找到相同的DLL,因为它们存在于多个子目录中。是否有一种简单的方法可以基于项元数据(即文件名和扩展名)进行规范化,从而获得唯一的单元测试DL

我正在尝试获取项目根目录下所有单元测试程序集的列表。我可以这样做:

<CreateItem Include="**\bin\**\*.UnitTest.*.dll">
   <Output TaskParameter="Include" ItemName="Items"/>
</CreateItem>


但是,这会多次找到相同的DLL,因为它们存在于多个子目录中。是否有一种简单的方法可以基于项元数据(即文件名和扩展名)进行规范化,从而获得唯一的单元测试DLL列表?还是我必须自己写任务?

我在网上搜索得很好,但找不到任何方法。如果有人知道一个干净的内置方式,那么请让我知道。同时,我写了一个简单的任务来完成这项工作。用法如下所示:

<NormalizeByMetadata Items="@(ItemsToNormalize)" MetadataName="Filename">
    <Output TaskParameter="NormalizedItems" ItemName="MyNormalizedItems"/>
</NormalizeByMetadata>
包含任务MSBuildHelper,支持命令RemovedUpplicateFiles


即使这是一个很老的解决方案,我自己也无法让Thomas solution正常工作,但我确实找到了一种仅使用msbuild v4.0的内置命令的解决方法:

<ItemGroup>
    <TestAssemblies Include="$(SolutionRoot)\**\bin\*.Tests.dll" />
    <TestItems Include="%(TestAssemblies.FileName)%(TestAssemblies.Extension)">
        <ItemPath>%(TestAssemblies.Identity)</ItemPath>
    </TestItems>
    <DistinctTestItems Include="@(TestItems->Distinct())"></DistinctTestItems>
</ItemGroup>
<Message Text="%(DistinctTestItems.ItemPath)" Importance="high" />

%(测试组件.标识)

文档:

如何为NormalizeByMetadata任务创建单元测试?这应该是公认的答案。内置的功能就是您所需要的。
<CreateItem Include="**\bin\**\*.UnitTest.*.dll">
    <Output TaskParameter="Include" ItemName="Items"/>
</CreateItem>
<MSBuild.ExtensionPack.Framework.MsBuildHelper TaskAction="RemoveDuplicateFiles" InputItems1="@(Items)">
    <Output TaskParameter="OutputItems" ItemName="Items"/>
</MSBuild.ExtensionPack.Framework.MsBuildHelper>
<ItemGroup>
    <TestAssemblies Include="$(SolutionRoot)\**\bin\*.Tests.dll" />
    <TestItems Include="%(TestAssemblies.FileName)%(TestAssemblies.Extension)">
        <ItemPath>%(TestAssemblies.Identity)</ItemPath>
    </TestItems>
    <DistinctTestItems Include="@(TestItems->Distinct())"></DistinctTestItems>
</ItemGroup>
<Message Text="%(DistinctTestItems.ItemPath)" Importance="high" />