msbuild - existe - Incluyendo archivos de contenido en.csproj que están fuera del cono del proyecto
msbuild reduce verbosity (7)
Creo que share lo share bien, por un lado, quieres usar la función de "enlace".
Sin embargo, solo es en parte correcto cuando dice que no se puede vincular a un árbol de directorios. Si bien esto es cierto cuando se intenta agregar los enlaces mediante la GUI de Visual Studio, MSBuild lo admite.
Si desea conservar la estructura del directorio, simplemente agregue la etiqueta %(RecursiveDir)
a su nodo <link>
:
<Content Include="../../MyContentFiles/**/*.*">
<Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
La página MSBuild Metadatos de elementos conocidos incluye más detalles sobre los metadatos a los que puede acceder.
Tengo un proyecto en 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 está gestionado. Por lo tanto, tengo que incluir todo lo que está debajo de él.
Cuando los incluyo como ''Contenido'' en el proyecto, se copian, pero la estructura del directorio se pierde. 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 directorio conservada?
Es necesario agregar el archivo como un enlace:
- Haga clic derecho en el proyecto en VS.
- Añadir -> Elemento existente ...
- Encuentra el archivo.
- Selecciónelo y.
- Agregar como enlace (desplegable en el botón Agregar en el cuadro de diálogo).
- Abra las propiedades del archivo y configure "Copiar en el directorio de salida" en "Copiar siempre".
PERO no puede hacerlo para el árbol de directorios.
En su lugar, necesita escribir una tarea posterior a la compilación para eso. Esta es una muestra que te hará mirar.
La respuesta de share agrega los archivos de contenido directamente a la solución, y se mostrarán en el explorador de soluciones. Cada vez que se agrega o elimina un archivo en el directorio original, Visual Studio no lo selecciona automáticamente. Además, cada vez que se elimina o agrega un archivo en el explorador de soluciones, el archivo del proyecto se altera y todos los archivos se incluyen por separado, en lugar de solo incluir la carpeta.
Para evitar esto, puede usar el mismo truco, pero póngalo en un archivo de proyecto separado y luego impórtelo.
El archivo de proyecto (por ejemplo, include.proj) se ve así:
<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 se metirá con este archivo, y solo agrega archivos como contenido durante una compilación. Los cambios en el directorio original siempre están incluidos. Los archivos no se mostrará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
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 en el directorio de destino $(TargetDirectory)
de su compilación (generalmente $(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 necesitaban ir en un directorio llamado MyContentFiles, podría 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" />
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>
Para incluir archivos en una carpeta para un proyecto .NET Core,
<ItemGroup>
<None Update="../../MyContentFiles/**/*.*">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
Y la propiedad de los elementos "Copiar al directorio de salida" será "Copiar si es más reciente":
Yo creo que
<Content Include="../../MyContentFiles/**/*.*">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
Es suficiente, ya que quieres todo en esa carpeta y subcarpetas