Tengo un proyecto de C # que dice MyProject.csproj ubicado en "C: \ Projects \ MyProject \". También tengo archivos que quiero copiar en el directorio de salida de este proyecto. Pero, los archivos están en la ubicación "C: \ MyContentFiles \", es decir, NO están dentro del cono del proyecto. Este directorio también tiene subdirectorios. El contenido del directorio no se gestiona. Por lo tanto, tengo que incluir todo lo que hay debajo.
Cuando los incluyo como 'Contenido' en el proyecto, se copian, pero se pierde la estructura del directorio. Hice algo como esto: -
<Content Include="..\..\MyContentFiles\**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
¿Cómo copio estos archivos / directorios de forma recursiva en el directorio de salida del proyecto con la estructura de directorios preservada?
Creo que @Dmytrii lo hace bien por un lado: desea utilizar la función de "enlace".
Sin embargo, solo tiene razón en parte cuando dice que no se puede vincular a un árbol de directorios. Si bien esto es cierto cuando se intenta agregar los enlaces utilizando la GUI de Visual Studio, MSBuild lo admite.
Si desea conservar la estructura del directorio, simplemente agregue la
%(RecursiveDir)
etiqueta a su<link>
nodo:<Content Include="..\..\MyContentFiles\**\*.*"> <Link>%(RecursiveDir)%(Filename)%(Extension)</Link> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content>
La página Metadatos de elementos conocidos de MSBuild detalla los metadatos a los que puede acceder.
fuente
<Content Include="..\..\MyContentFiles\**\*.*">
- tenga\*.*
en cuenta el al final de la ruta.La respuesta de Mandark agrega los archivos de contenido directamente a la solución y aparecerán en el explorador de soluciones. Siempre que se agrega o elimina un archivo en el directorio original, Visual Studio no lo detecta automáticamente. Además, cada vez que se elimina o agrega un archivo en el explorador de soluciones, el archivo del proyecto se modifica y todos los archivos se incluyen por separado, en lugar de solo incluir la carpeta.
Para evitar esto, puede utilizar el mismo truco, pero ponerlo en un archivo de proyecto separado y luego importarlo.
El archivo del proyecto (por ejemplo, include.proj) tiene este aspecto:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> <Content Include="..\..\MyContentFiles\**"> <Link>%(RecursiveDir)%(Filename)%(Extension)</Link> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> </ItemGroup> </Project>
En su propio archivo de proyecto, agregue la siguiente línea
<Import Project="include.proj" />
Visual Studio no interferirá con este archivo y solo agregará archivos como contenido durante una compilación. Los cambios en el directorio original siempre se incluyen. Los archivos no aparecerán en su explorador de soluciones, pero se incluirán en el directorio de salida.
Aprendí este truco aquí: http://blogs.msdn.com/b/shawnhar/archive/2007/06/06/wildcard-content-using-msbuild.aspx
fuente
Lo siguiente, que agregaría al final de su archivo de proyecto, copiará sus archivos de contenido manteniendo la estructura del directorio en un evento posterior a la compilación al directorio
$(TargetDirectory)
de destino de su compilación (normalmente$(MSBuildProjectDirectory)\bin\Debug
).<ItemGroup> <ExtraContent Include="$(MSBuildProjectDirectory)\..\..\MyContentFiles\**" /> </ItemGroup> <Target Name="AfterBuild"> <Copy SourceFiles="@(ExtraContent)" DestinationFiles="@(ExtraContent->'$(TargetDir)\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="true" /> </Target>
Si estos archivos necesitan ir a un directorio llamado MyContentFiles, puede agregar esto antes de la copia:
<MakeDir Directories="$(TargetDir)\MyContentFiles" Condition=" !Exists('$(TargetDir\MyContentFiles') " />
y cambio
<Copy SourceFiles="@(ExtraContent)" DestinationFiles="@(ExtraContent->'$(TargetDir)\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="true" />
A
<Copy SourceFiles="@(ExtraContent)" DestinationFiles="@(ExtraContent->'$(TargetDir)\MyContentFiles\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="true" />
fuente
Yo creo que
<Content Include="..\..\MyContentFiles\**\*.*"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content>
Es suficiente, ya que quieres todo en esa carpeta y subcarpetas
fuente
Para incluir archivos en una carpeta para un proyecto .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>
Y la propiedad de los elementos "Copiar al directorio de salida" será "Copiar si es más reciente":
fuente
Para ignorar un archivo en un proyecto .Net Core:
<ItemGroup> <Content Include="appsettings.local.json"> <CopyToOutputDirectory Condition="Exists('appsettings.local.json')">PreserveNewest</CopyToOutputDirectory> </Content> </ItemGroup>
fuente