MSBUild:复制具有基于原始名称的文件(遵循模式)

dar*_*mos 16 msbuild design-patterns copy rename

我在文件夹中有一组文件.它们都具有与DR __.*模式匹配的名称.我想将它们复制到另一个文件夹,但删除DR__前缀.我怎么能用MSBuild做到这一点?我曾经这样使用NAnt这样做:

<mkdir dir="${ClientPath + '\bin\' + ConfigurationName + '\Parameters'}"/>
<foreach item="File" property="Filename" in="CVParameters">
    <if test="${string::contains(Filename, Client + '_')}">
        <property name="newFilename" value="${ string::substring( Filename, string::last-index-of(Filename, '__') + 2, string::get-length(Filename) - string::last-index-of(Filename, '__') - 2) }"/>
        <copy file="${ Filename  }" tofile="${ ClientPath + '\bin\' + ConfigurationName + '\Parameters\' + newFilename }" overwrite="true"/>
    </if>
</foreach>
Run Code Online (Sandbox Code Playgroud)

Ser*_*kov 14

我同意@ Si的解决方案.但是使用MSBuild 4.0,您可以使用内置功能.NAnt脚本比我的清晰得多.但我会将其添加为仅显示MSBuild 4.0技术的解决方案:

    <ItemGroup>
       <CVParameters Include="$(YourBaseDir)\**\DR__*" />
    </ItemGroup>

    <Target Name="CopyAndRename" 
            Condition="'@(CVParameters)'!=''"
            Outputs="%(CVParameters.Identity)">
         <PropertyGroup>
            <OriginalFileName>%(CVParameters.FileName)%(CVParameters.Extension)</OriginalFileName>          
            <Prefix>DR__</Prefix>
            <PrefixLength>$(Prefix.Length)</PrefixLength>
            <OriginalFileNameLength>$(OriginalFileName.Length)</OriginalFileNameLength>
            <SubstringLength>$([MSBuild]::Subtract($(OriginalFileNameLength),$(PrefixLength)))</SubstringLength>
            <ModifiedFileName>$(OriginalFileName.Substring($(PrefixLength),$(SubstringLength)))</ModifiedFileName>
            <DestinationFullPath>$([System.IO.Path]::Combine($(DestinationDir),$(ModifiedFileName)))</DestinationFullPath>
         </PropertyGroup>                                                                                                                                         

         <Copy SourceFiles="%(CVParameters.FullPath)" 
               DestinationFiles="@(DestinationFullPath)" 
               SkipUnchangedFiles="true" />
    </Target>
Run Code Online (Sandbox Code Playgroud)

编辑(由OP):为了得到这个工作,我不得不更换$(DestinationFullPath)Copy@(DestinationFullPath),以匹配源和目标文件的数量.此外,我不得不更改前缀DR__,因为DR__.不起作用.


Iva*_*gin 10

最近我不得不解决类似的任务,我使用Item的元数据来完成它.该解决方案的优点是:

  1. 小构建脚本大小.
  2. 使用标准System.String函数获取修改后的名称.
  3. 自定义元数据是基于现有项目的新项目定义进行复制(例如,项目<TempItemsBak Include="@(TempItems-> ... CustomTransform ... )">将获取原始项目的元数据值,以便您可以将其用于进一步处理)

<Project DefaultTargets="CopyNoPrefix" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <PropertyGroup>
    <InputDir Condition="'$(InputDir)' == '' ">.</InputDir>
    <OutputDir Condition="'$(OutputDir)' == '' ">Output</OutputDir>
  </PropertyGroup>

  <ItemGroup>
    <CVParameters Include="$(InputDir)\**\DR__.*" />
  </ItemGroup>

  <Target Name="CopyNoPrefix">
    <ItemGroup>
      <!-- Items with new name. Use System.String's Remove method to get full file name without prefix -->
      <!-- http://msdn.microsoft.com/en-us/library/vstudio/ee886422(v=vs.100).aspx -->
      <TempItems Include="@(CVParameters->'%(Filename)%(Extension)'->Remove(0, 5))">
        <!-- Define metadata based on original item for next step -->
        <OriginalPath>%(Identity)</OriginalPath>
        <SavedRecursiveDir>%(RecursiveDir)</SavedRecursiveDir>
      </TempItems>
    </ItemGroup>

    <!-- Use new items along with their metadata for copying -->
    <Copy SourceFiles="@(TempItems->'%(OriginalPath)')" DestinationFiles="@(TempItems->'$(OutputDir)\%(SavedRecursiveDir)%(Identity)')" />
  </Target>

</Project>
Run Code Online (Sandbox Code Playgroud)