这是一个MSBuild脚本:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="AugmentItemGroup" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
 <ItemGroup>
   <ItmGrp Include="File1.txt">
       <Dest>dest\%(FileName)%(Extension)</Dest>
   </ItmGrp>
   <ItmGrp Include="File2.txt">
       <Dest>dest\%(FileName)%(Extension)</Dest>
   </ItmGrp>
   <ItmGrp Include="File3.txt">
       <Dest>dest\%(FileName)%(Extension)</Dest>
   </ItmGrp>
  </ItemGroup>

   <Target Name="AugmentItemGroup">
     <ItemGroup>
      <ItmGrp Include="File4.txt">
        <Dest>dest\%(FileName)%(Extension)</Dest>
      </ItmGrp>
     </ItemGroup>
     <Message Text="%(ItmGrp.FullPath) to %(ItmGrp.Dest)" />
   </Target>
</Project>


我期望的输出是:

  D:\t\File1.txt to dest\File1.txt
  D:\t\File2.txt to dest\File2.txt
  D:\t\File3.txt to dest\File3.txt
  D:\t\File4.txt to dest\File4.txt


但是结果是:

  D:\t\File1.txt to dest\File1.txt
  D:\t\File2.txt to dest\File2.txt
  D:\t\File3.txt to dest\File3.txt
  D:\t\File4.txt to dest\File1.txt
  D:\t\File4.txt to dest\File2.txt
  D:\t\File4.txt to dest\File3.txt


当ItemGroup位于目标内部时,为什么%(FileName)%(Extension)众所周知的元数据引用的行为会有所不同?

是否有可能在目标内部获得“目标外部”的行为?

最佳答案

这将提供您想要的输出。尽管在一般情况下这可能不是正确的方法,但通过将自定义元数据作为计算出的项目定义的一部分,它确实避免了与“ 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

10-02 03:04
查看更多