Попытка исключить определенные расширения, выполняющие рекурсивную копию (MSBuild)

Я пытаюсь использовать MSBuild для чтения в списке файлов из текстового файла, а затем выполнять рекурсивную копию, копируя содержимое этих файлов каталогов в какую-либо промежуточную область, исключая определенные расширения (например, файлы .tmp )

Мне удалось выполнить большую часть вышеизложенного довольно просто с помощью CreateItem и задачи копирования MSBuild, независимо от того, что я делаю, задача CreateItem просто игнорирует мой параметр Exclude:

<PropertyGroup>
  <RootFolder>c:\temp</RootFolder>
  <ExcludeFilter>*.tmp</ExcludeFilter>
  <StagingDirectory>staging</StagingDirectory>
</PropertyGroup>
<ItemGroup>
  <InputFile Include="MyFile.txt" />
</ItemGroup>

<Target Name="Build">
  <ReadLinesFromFile File="@(InputFile)">
    <Output ItemName="AllFolders" TaskParameter="Lines" />
  </ReadLinesFromFile>

  <CreateItem Include="$(RootFolder)\%(AllFolders.RelativeDir)**"
              Exclude="$(ExcludeFilter)">
    <Output ItemName="AllFiles" TaskParameter="Include" />
  </CreateItem>

  <Copy SourceFiles="@(AllFiles)"
        DestinationFolder="$(StagingDirectory)\%(RecursiveDir)" 

Пример содержимого "MyFile.txt":

somedirectory\
someotherdirectory\

(I.e. пути относятся к $(RootFolder) - упомяните об этом, потому что я где-то читал, что это может быть актуально)

Я пробовал множество различных комбинаций фильтров Exclude, но, похоже, я никогда не смог заставить его правильно исключить мои .tmp файлы - есть ли способ сделать это с помощью MSBuild, не прибегая к xcopy?

Ответы

Ответ 1

Вы должны указать Exclude в абсолютном пути и изменить подстановочный знак exclude для включения подкаталога

Если вы используете абсолютный путь для Include, вы должны использовать абсолютный путь для Exclude. Если вы используете относительный путь для Include, вы должны использовать относительный путь для обоих.

<PropertyGroup>
  <RootFolder>c:\temp</RootFolder>
  <ExcludeFilter>**\*.tmp</ExcludeFilter>
  <StagingDirectory>staging</StagingDirectory>
</PropertyGroup>
<ItemGroup>
  <InputFile Include="MyFile.txt" />
</ItemGroup>

<Target Name="Build">
  <ReadLinesFromFile File="@(InputFile)">
    <Output ItemName="AllFolders" TaskParameter="Lines" />
  </ReadLinesFromFile>

  <CreateItem Include="$(RootFolder)\%(AllFolders.RelativeDir)**"
              Exclude="$(RootFolder)\%(AllFolders.RelativeDir)$(ExcludeFilter)">
    <Output ItemName="AllFiles" TaskParameter="Include" />
  </CreateItem>

  <Copy SourceFiles="@(AllFiles)"
        DestinationFolder="$(StagingDirectory)\%(RecursiveDir)"/>
</Target>

Несколько исключений и абсолютный путь

Если вы хотите исключить несколько элементов, нет чистого способа, когда вы используете абсолютный путь, но вы можете сделать с Remove.

Первый способ: использование Удалить и элемент

<PropertyGroup>
  <RootFolder>c:\temp</RootFolder>
</PropertyGroup>

<ItemGroup>
  <InputFile Include="MyFile.txt" />
  <!-- Exclude are defined here -->
  <ExcludeFilters Include="$(RootFolder)\**\*.tmp"/>
  <ExcludeFilters Include="$(RootFolder)\**\*.bmp"/>
</ItemGroup>

<Target Name="Build">
  <ReadLinesFromFile File="@(InputFile)">
    <Output ItemName="AllFolders" TaskParameter="Lines" />
  </ReadLinesFromFile>

  <CreateItem Include="$(RootFolder)\%(AllFolders.RelativeDir)**">
    <Output ItemName="AllFiles" TaskParameter="Include" />
  </CreateItem>

  <!-- Removing the wrong extension in item -->
  <ItemGroup>
    <AllFiles Remove="@(ExcludeFilters)"/>
  </ItemGroup>

  <Copy SourceFiles="@(AllFiles)"
        DestinationFolder="$(StagingDirectory)\%(RecursiveDir)"/>
</Target>

Второй способ: использование Удалить и условие

<Target Name="Build">
  <ReadLinesFromFile File="@(InputFile)">
    <Output ItemName="AllFolders" TaskParameter="Lines" />
  </ReadLinesFromFile>

  <CreateItem Include="$(RootFolder)\%(AllFolders.RelativeDir)**">
    <Output ItemName="AllFiles" TaskParameter="Include" />
  </CreateItem>

  <!-- Removing the wrong extension in item -->
  <ItemGroup>
    <AllFiles Remove="@(AllFiles)" Condition="'%(Extension)' == '.tmp'"/>
    <AllFiles Remove="@(AllFiles)" Condition="'%(Extension)' == '.bmp'"/>
  </ItemGroup>

  <Copy SourceFiles="@(AllFiles)"
        DestinationFolder="$(StagingDirectory)\%(RecursiveDir)"/>
</Target>