2012-04-18 8 views
8

¿Es posible especificar una carpeta diferente para la salida del siguiente archivo?¿Puedo especificar la ruta de salida para la etiqueta MSBuild <Content>?

<Content Include="test.stl"> 
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> 
</Content> 
+0

¿Has descubierto cómo hacerlo? –

+0

Aún no, lo siento. – abenci

+1

Este enlace no muestra cómo especificar una carpeta diferente con la etiqueta de contenido pero parece una solución que puede permitirle hacer lo que desea ... http://stackoverflow.com/questions/7643615/how-can- i-get-msbuild-to-copy-all-files-marked-as-content-to-a-folder-preservin –

Respuesta

5

Puedes, pero no con 'Contenido'. Depende de la tarea del elemento, pero la mayoría de los integrados en los que podría hackear, merecen la pena o los efectos colaterales.

Hay una ruta básica muy usada para tratar con esto :) Esto también evita la forma desagradable de shell de cmd de Postbuch si está haciendo .Net, y usa el proceso de compilación real.

No vi ninguna otra respuesta como esta, usando strieght up MSBuild, donde creo que el corazón de la pregunta de OP es. Este es el concepto básico, y el camino más corto, que excluye la búsqueda de un tipo de elemento que tenga un parámetro de ruta 'relativa al camino de salida' sin efectos secundarios.

1) postproceso Estilo:

<ItemGroup> 
    ... 
    <MyTargets Include="test.stl"/> 
    ... 
</ItemGroup> 

A continuación, en la parte inferior (usando cualquier caminos que está después):

<PropertyGroup> 
    <MyDeployDir>$(SolutionDir)$(Configuration)</MyDeployDir> 
    <MyOtherDeployDir>$(SolutionDir)$(Configuration)\Templates</MyDeployDir> 
</PropertGroup> 

Luego, su existente acumulación MS incluye (No añadir este, está aquí como un marcador):

<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> 

Luego el 'Tras la compilación':

<Target Name="AfterBuild"> 
    <Copy SourceFiles="@(MyTargets)" DestinationFolder="$(MyDeployDir)" SkipUnchangedFiles="true" /> 
    <Copy SourceFiles="@(MyOtherTargets)" DestinationFolder="$(MyOtherDeployDir)" SkipUnchangedFiles="true" /> 
    <Copy SourceFiles="@(MyTargets2)" DestinationFolder="$(MyDeployDir)\IHeardYourMomLikesGrapeNuts" SkipUnchangedFiles="true" /> 
</Target> 

La cuestión es que fundemental proyecto de artículos no hacen nada por defecto, que tienen un tipo como 'contenido' o 'MyTarget'. Son esos tipos que dicen lo que sucederá. Es posible que pueda encontrar una tarea, tipo o compilación de script que tenga lo que desea, pero no hay nada intrínseco acerca de un elemento en un grupo de elementos en cuanto a lo que sucederá con ese archivo durante la compilación. Lo anterior es un equilibrio entre el poder de una 'tarea' especialmente construida pero sin ningún problema.

Una vez que añadir

<ItemGroup> 
    <MyOutFiles Include="xxx.xxx" /> 

una vez que el archivo de proyecto, a continuación, aparecerá en la lista BuildAction para cualquier archivo, donde se puede establecer en cualquier archivo sin tener que editar el archivo proj manualmente.


2) En un paso

En versiones posteriores de MSBuild se pueden incrustar una 'ItemGroup' en el interior de destino del 'AfterBuild' y hacer lo anterior o hacer otras cosas de lujo sin tocar el resto del archivo . Esto permite, por ejemplo, obtener el resultado de la compilación usando un simple Incluir y desplazarlo a otro lugar. Esto es todo sin hacer nada con RoboCopy ni recurrir al procesamiento de funciones de compilación de objetivos más complicado.

<Target Name="AfterBuild"> 
    <ItemGroup> 
    <MyOutFiles Include="$(OutDir)*.*" /> 
    </ItemGroup> 
    <Copy SourceFiles="@(MyOutFiles)" DestinationFolder="$(SolutionDir)\Application" SkipUnchangedFiles="true" /> 

Editar (debido al voto hacia abajo?, carteles comentan desde que se eliminaron):

Para eliminar la ambigüedad de los métodos posibles y para reiterar, este método no usa MSBuild 'funciones' o tareas alternativas como 'RoboCopy' pero se suponía que mostrara un estilo MSBuild más puro usando funcionalidad central como uno lo usaría para hacer tareas de elementos como 'Contenido'.

La pregunta era ¿puedo especificar una 'carpeta diferente para el siguiente archivo' y puedo hacer esto para la etiqueta de contenido. Puede reenrutar todas las funciones de BuildAction usando MSBuild, sin embargo, no creo que esa sea la pregunta.

Puede hacer esto es un paso como se muestra arriba, así que no creo que esto sea más complicado y cree que es más fácil de leer. A continuación se muestra la forma abreviada, y le permite crear su propia BuildAction que se puede manejar de cualquier forma que quiera. Entonces no, no puedes decirle a 'Contenido' que elija otra carpeta para un archivo particular marcado como 'Contenido', pero puedes hacer otra acción de compilación que sea bastante fácil. También puede insertar meta información en la etiqueta StlFiles que dirige la acción para que pueda establecerla en la etiqueta o hacer que StlFiles se enganche antes en el proceso como lo haría el contenido, pero eso es más complicado.

<StlFiles Include="test.stl" />   
... 
<Target Name="AfterBuild"> 
    <Copy SourceFiles="@(StlFiles)" DestinationFolder="$(SolutionDir)\Release\MyTypes" SkipUnchangedFiles="true" /> 
+0

La respuesta no está mal, funciona.El enlace proporcionado muestra una forma diferente de usar las funciones de script, que evité específicamente, como evitar la tarea de RoboCopy. El enlace proporcionado arroja todo el contenido a un lugar, este hace un archivo. Él pidió un archivo. La pregunta era: ¿puede una tarea de elemento usar una ruta de salida alternativa? La respuesta es sí y no, 'contenido' no puede, pero otras tareas pueden, pero aquí hay una manera de hacer una que pueda controlar. – Celess

+0

Hubo un comentario sobre mi primer comentario, que aparentemente fue eliminado; solo digo ... entonces lo de arriba no parece aleatorio. Fue un comentario de voto negativo al que estaba respondiendo, y por qué la sección de edición existe en la respuesta. El comentario que falta ahora tiene una redacción bastante enérgica, algo en el sentido de "voto negativo debido no solo a que esta respuesta es incorrecta, sino que hace que algo simple sea mucho más complicado de lo que es necesario" por BitwiseMan. – Celess

+0

El enlace al que hizo referencia fue: http://stackoverflow.com/questions/7643615/how-can-i-get-msbuild-to-copy-all-files-marked-as-content-to-a-folder-preservin – Celess

0

No hay forma de especificar una carpeta de salida, además, que yo sepa, pero se puede copiar el archivo antes o después de la construcción.

0

Esta funcionalidad no está integrada en el elemento Contenido. Pero puede virar al agregar un objetivo a su archivo de proyecto.

En su proyecto que tiene actualmente la siguiente: (etiqueta de "Proyecto" antes del cierre)

<ItemGroup> 
    <Content Include="test.stl"> 
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> 
    </Content> 
</ItemGroup> 

Suponiendo que desea que un archivo específico copiado en una ubicación diferente, añadir esto al final:

<Target Name="CopyStl" AfterTargets="AfterBuild"> 
    <!-- One or the other of these Copy tasks should do what you want --> 
    <Copy Condition="'%(Identity)' == 'test.stl'" SourceFiles="@(Content)" SkipUnchangedFiles="true" DestinationFolder="$(OutputPath)\path\under\outputpath" /> 
    <Copy Condition="'%(Identity)' == 'test.stl'" SourceFiles="@(Content)" SkipUnchangedFiles="true" DestinationFolder="$(MSBuildProjectDirectory)\..\path\outside\project" /> 
</Target> 

Si desea agregar un poco más de los archivos a copiar en la misma carpeta, probar este lugar:

<Target Name="CopySomeFiles" AfterTargets="AfterBuild"> 
    <!-- One or the other of these Copy tasks should do what you want --> 
    <Copy Condition="'%(Identity)' == 'test.stl' AND '%(Identity)' == 'test2.stl'" SourceFiles="@(Content)" SkipUnchangedFiles="true" DestinationFolder="$(OutputPath)\path\under\outputpath" /> 
    <Copy Condition="'%(Identity)' == 'test.stl' AND '%(Identity)' == 'test2.stl'" SourceFiles="@(Content)" SkipUnchangedFiles="true" DestinationFolder="$(MSBuildProjectDirectory)\..\path\outside\project" /> 
</Target 
0

Una carpeta de salida diferente se puede especificar mediante el uso de los metadatos Link en None/Content artículos:

<Content Include="test.stl"> 
    <Link>some\folder\%(Filename)%(Extension)</Link> 
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> 
</Content> 

Al utilizar comodines en una declaración incluirá, esta es también la manera de preservar la jerarquía de directorios, incluso para archivos procedentes de fuera del directorio del proyecto:

<Content Include="..\shared\**\*"> 
    <Link>some\folder\%(RecursiveDir)%(Filename)%(Extension)</Link> 
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> 
</Content> 

En los proyectos basados ​​en SDK (por defecto para proyectos ASP.NET Core/Core .NET/.NET estándar) utilizando un SDK 2.0.0+, el mismo se puede conseguir mediante el LinkBase metadata:

<Content Include="..\shared\**\*" LinkBase="some\folder" CopyToOutputDirectory="PreserveNewest" /> 
Cuestiones relacionadas