Пакетное копирование списка элементов с помощью MSBuild Task RoboCopy
Есть список каталогов источника и назначения, определенных в. Мне нужна одна задача / цель для выполнения robocopy в соответствии с определенными свойствами группы элементов.
<ItemGroup>
<ItemToCopy Include="$(RootPath)\Audi">
<WhereToCopy>$(FinalFolder)\Audi</WhereToCopy>
<WhatToCopy>*.svc</WhatToCopy>
</ItemToCopy>
<ItemToCopy Include="$(RootPath)\Custom">
<WhereToCopy>$(FinalFolder)\Custom</WhereToCopy>
<WhatToCopy>*.svc</WhatToCopy>
</ItemToCopy>
<ItemToCopy Include="$(RootPath)\Audi\bin">
<WhereToCopy>$(FinalFolder)\Audi\bin</WhereToCopy>
<WhatToCopy>*.*</WhatToCopy>
</ItemToCopy>
<ItemToCopy Include="$(RootPath)\Custom\bin">
<WhereToCopy>$(FinalFolder)\Custom\bin</WhereToCopy>
<WhatToCopy>*.*</WhatToCopy>
</ItemToCopy>
Я попробовал следующий код, ожидая выполнить операцию копирования для каждого элемента в папке развертывания.
<Target Name="CopyAll">
<RoboCopy
Source="@(ItemToCopy)"
Destination="%(ItemToCopy.WhereToCopy)" Files="ItemtoCopy.Whattocopy"/>
</Target>
Кроме того, если мы видим элементы 1 и 2 (также 3 и 4), они одинаковы в том смысле, что копируют одинаковые типы файлов из их%ItemName по тому же пути с подкаталогом%ItemName. Было бы здорово, если бы мы также могли избежать этого дополнительного запаха кода. Надеюсь, что-то вроде ниже, чтобы работать:
<ItemToCopy Include="$(RootPath)\@PublishProjects">
<WhereToCopy>$(FinalFolder)\@PublishProjects</WhereToCopy>
<WhatToCopy>*.svc</WhatToCopy>
</ItemToCopy>
where,
<ItemGroup>
<PublishProjects Include="Audi" />
<PublishProjects Include="Custom" />
</ItemGroup>
2 ответа
Хорошо, этот ответ, который я дал, пропускает использование robocopy, которое, как я признаю, является специфической частью вашего вопроса.
@ И% все еще остаются в силе (вы не можете смешивать их использование), и именно в этом вы ошиблись в своей цели CopyAll.
<Target Name="CopyAll">
<RoboCopy
Source="@(ItemToCopy)"
Destination="@(ItemToCopy->'%(WhereToCopy)')" Files="@(ItemtoCopy->'%(Whattocopy)')"/>
</Target>
Ознакомьтесь с справкой по преобразованиям, чтобы лучше понять, как их использовать. https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-transforms
Вы не можете смешивать @ и%. Оба из них указывают на операцию над группой товаров. Использование% выполняет операцию один раз для каждого элемента в группе элементов. @ выполняет операцию один раз для всей группы товаров. Обратите внимание, что не все задачи поддерживают группы элементов.
Если вы используете @, то вы используете "преобразование", которое имеет необычный синтаксис. https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-transforms
Кроме того, группы товаров предназначены для соответствия файлов для вас. Указание папок работает и относится к папке, но одна из сильных сторон msbuild - это поиск файлов для вас.
Вместо
<ItemToCopy Include="$(RootPath)\Audi">
<WhereToCopy>$(FinalFolder)\Audi</WhereToCopy>
<WhatToCopy>*.svc</WhatToCopy>
</ItemToCopy>
Я бы пошел с
<ItemToCopy Include="$(RootPath)Audi\*.svc">
<TargetSubDir>Audi\</TargetSubDir>
</ItemToCopy>
Тогда ваша цель будет больше похожа
<Target Name="CopyFiles">
<Copy Condition="@(ItemToCopy)!=''"
SourceFiles="@(ItemToCopy)"
DestinationFiles="@(ItemToCopy->'$(FinalFolder)%(TargetSubDir)%(RecursiveDir)%(Filename)%(Extension)')"
OverwriteReadOnlyFiles="true"
SkipUnchangedFiles="true" />
</Target>
Помните, это соглашение msbuild, что все свойства / метаданные, представляющие каталог, включают в себя завершающий слеш.