У меня есть проект C #, скажем, MyProject.csproj, расположенный в «C: \ Projects \ MyProject \». У меня также есть файлы, которые я хочу скопировать в выходной каталог этого проекта. Но файлы находятся в расположении «C: \ MyContentFiles \», то есть они НЕ находятся в конусе проекта. В этом каталоге также есть подкаталоги. Содержание каталога не управляется. Следовательно, я должен включить все, что находится под ним.
Когда я включаю их в проект как «Контент», они копируются, но структура каталогов теряется. Я сделал что-то вроде этого: -
<Content Include="..\..\MyContentFiles\**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
Как мне рекурсивно скопировать эти файлы / каталоги в выходной каталог проекта с сохранением структуры каталогов?
Я считаю, что @Dmytrii правильно понимает это с одной стороны - вы хотите использовать функцию «ссылки».
Однако он прав лишь отчасти, когда говорит, что вы не можете ссылаться на дерево каталогов. Хотя это действительно так, когда вы пытаетесь добавить ссылки с помощью графического интерфейса Visual Studio, MSBuild поддерживает это.
Если вы хотите сохранить структуру каталогов, просто добавьте
%(RecursiveDir)
тег в свой<link>
узел:<Content Include="..\..\MyContentFiles\**\*.*"> <Link>%(RecursiveDir)%(Filename)%(Extension)</Link> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content>
На странице « Метаданные хорошо известных элементов MSBuild» более подробно описаны доступные вам метаданные.
источник
<Content Include="..\..\MyContentFiles\**\*.*">
- обратите внимание на значок\*.*
в конце пути.Ответ Mandark добавляет файлы содержимого непосредственно в решение, и они будут отображаться в проводнике решения. Каждый раз, когда файл добавляется или удаляется в исходном каталоге, он не обрабатывается Visual Studio автоматически. Кроме того, всякий раз, когда файл удаляется или добавляется в обозревателе решений, файл проекта изменяется, и все файлы включаются отдельно, а не просто включают папку.
Чтобы предотвратить это, вы можете использовать тот же прием, но поместить его в отдельный файл проекта, а затем импортировать.
Файл проекта (например, include.proj) выглядит так:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> <Content Include="..\..\MyContentFiles\**"> <Link>%(RecursiveDir)%(Filename)%(Extension)</Link> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> </ItemGroup> </Project>
В вашем собственном файле проекта добавьте следующую строку
<Import Project="include.proj" />
Visual Studio не будет связываться с этим файлом и просто добавляет файлы в качестве содержимого во время сборки. Всегда учитываются изменения в исходном каталоге. Файлы не будут отображаться в обозревателе решений, но будут включены в выходной каталог.
Поднял этот трюк здесь: http://blogs.msdn.com/b/shawnhar/archive/2007/06/06/wildcard-content-using-msbuild.aspx
источник
Следующее, которое вы должны добавить в конец файла проекта, скопирует ваши файлы содержимого, поддерживающие структуру каталогов в событии после сборки, в целевой каталог
$(TargetDirectory)
вашей сборки (обычно$(MSBuildProjectDirectory)\bin\Debug
).<ItemGroup> <ExtraContent Include="$(MSBuildProjectDirectory)\..\..\MyContentFiles\**" /> </ItemGroup> <Target Name="AfterBuild"> <Copy SourceFiles="@(ExtraContent)" DestinationFiles="@(ExtraContent->'$(TargetDir)\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="true" /> </Target>
Если эти файлы нужно было поместить в каталог с именем MyContentFiles, вы можете добавить это перед копией:
<MakeDir Directories="$(TargetDir)\MyContentFiles" Condition=" !Exists('$(TargetDir\MyContentFiles') " />
и изменить
<Copy SourceFiles="@(ExtraContent)" DestinationFiles="@(ExtraContent->'$(TargetDir)\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="true" />
Чтобы
<Copy SourceFiles="@(ExtraContent)" DestinationFiles="@(ExtraContent->'$(TargetDir)\MyContentFiles\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="true" />
источник
Я думаю
<Content Include="..\..\MyContentFiles\**\*.*"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content>
Достаточно, так как вы хотите, чтобы все в этой папке и подпапках
источник
Чтобы включить файлы в папку для проекта .NET Core,
<!--Just files--> <ItemGroup> <None Update="..\..\MyContentFiles\**\*.*"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> </ItemGroup> <!--Content files--> <ItemGroup> <Content Include="..\..\MyContentFiles\**\*.*" Link="MyContentFiles\%(RecursiveDir)%(Filename)%(Extension)"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> </ItemGroup>
И свойство элементов «Копировать в выходной каталог» будет «Копировать, если новее»:
источник
Чтобы игнорировать файл в проекте .Net Core:
<ItemGroup> <Content Include="appsettings.local.json"> <CopyToOutputDirectory Condition="Exists('appsettings.local.json')">PreserveNewest</CopyToOutputDirectory> </Content> </ItemGroup>
источник