Это даст желаемый результат. Хотя в общем случае это может быть неправильный подход, он избегает пакетирования, которое происходит с «File4», делая пользовательские метаданные частью вычисляемого определения элемента:
<Project
xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
DefaultTargets="AugmentItemGroup"
ToolsVersion="4.0">
<ItemDefinitionGroup>
<ItmGrp>
<Dest>dest\%(FileName)%(Extension)</Dest>
</ItmGrp>
</ItemDefinitionGroup>
<ItemGroup>
<ItmGrp Include="File1.txt" />
<ItmGrp Include="File2.txt" />
<ItmGrp Include="File3.txt" />
</ItemGroup>
<Target Name="AugmentItemGroup">
<ItemGroup>
<ItmGrp Include="File4.txt" />
</ItemGroup>
<Message Text="%(ItmGrp.FullPath) to %(ItmGrp.Dest)" />
</Target>
</Project>
редактирование:
Если (как говорит ваш комментарий ниже) каждый элемент имеет различное значение для% (Dest), вам просто нужно рассчитать окончательное значение:
<Project ...>
<ItemDefinitionGroup>
<ItmGrp>
<_Dest />
</ItmGrp>
</ItemDefinitionGroup>
<ItemGroup>
<ItmGrp Include="File1.txt"><Dest>dest1</Dest></ItmGrp>
<ItmGrp Include="File2.txt"><Dest>dest2</Dest></ItmGrp>
<ItmGrp Include="File3.txt"><Dest>dest3</Dest></ItmGrp>
</ItemGroup>
<Target Name="AugmentItemGroup">
<ItemGroup>
<ItmGrp Include="File4.txt"><Dest>dest4</Dest></ItmGrp>
<ItmGrp>
<_Dest>%(Dest)\%(FileName)%(Extension)</_Dest>
</ItmGrp>
</ItemGroup>
<Message Text="%(ItmGrp.FullPath) to %(ItmGrp._Dest)" />
</Target>
</Project>
Извлечено из MSBuild Trickery Трюки # 70, 71