3

这是一个 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

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

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

4

1 回答 1

5

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

于 2012-02-11T20:29:49.923 回答