Попытка исключить определенные расширения, делающие рекурсивное копирование (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\
(То есть пути относительно $(RootFolder)
- упомяните это, потому что я где-то читал, что это может быть актуально)
Я перепробовал множество различных комбинаций фильтров исключения, но, похоже, я никогда не смог заставить его корректно исключать мои файлы.tmp - есть ли способ сделать это с MSBuild, не прибегая к xcopy?
1 ответ
Вы должны указать 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
,
Первый способ: использование Remove и item
<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>
Второй способ: использование Remove и условие
<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>