2008-09-23 20 views
68

Solo me pregunto si alguien podría ayudarme con algunos scripts de msbuild que estoy tratando de escribir. Lo que me gustaría hacer es copiar todos los archivos y subcarpetas de una carpeta a otra usando msbuild.Copie todos los archivos y carpetas usando msbuild

{ProjectName} 
     |----->Source 
     |----->Tools 
       |----->Viewer 
         |-----{about 5 sub dirs} 

Lo que necesito para ser capaz de hacer es copiar todos los archivos y subcarpetas de la carpeta de herramientas en la carpeta de depuración de la aplicación. Este es el código que tengo hasta ahora.

<ItemGroup> 
<Viewer Include="..\$(ApplicationDirectory)\Tools\viewer\**\*.*" /> 
</ItemGroup> 

<Target Name="BeforeBuild"> 
     <Copy SourceFiles="@(Viewer)" DestinationFolder="@(Viewer->'$(OutputPath)\\Tools')" /> 
    </Target> 

El script de construcción se ejecuta pero no copia ninguno de los archivos o carpetas.

Gracias

Respuesta

3

Por favor, intenta especificar el directorio de destino concreto en lugar de

DestinationFolder="@(Viewer->'$(OutputPath)\\Tools')" ? 

no soy muy hábil con sintaxis avanzada MSBuild, pero

@(Viewer->'$(OutputPath)\\Tools') 

ve raro para mí. La escritura se ve bien, por lo que el problema podría estar en los valores de $(ApplicationDirectory) y $(OutputPath)

EDIT:

Aquí es un blog que podrían ser útiles:

How To: Recursively Copy Files Using the Task

+1

+1 para el enlace, que es más conciso que la respuesta aceptada de zXen. –

+1

+1 para el enlace, thx .. way easier – crabCRUSHERclamCOLLECTOR

67

Creo que el problema podría ser en cómo está creando su ItemGroup y llamando a la tarea Copiar. A ver si esto tiene sentido:

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5"> 
    <PropertyGroup> 
     <YourDestinationDirectory>..\SomeDestinationDirectory</YourDestinationDirectory> 
     <YourSourceDirectory>..\SomeSourceDirectory</YourSourceDirectory> 
    </PropertyGroup> 

    <Target Name="BeforeBuild"> 
     <CreateItem Include="$(YourSourceDirectory)\**\*.*"> 
      <Output TaskParameter="Include" ItemName="YourFilesToCopy" /> 
     </CreateItem> 

     <Copy SourceFiles="@(YourFilesToCopy)" 
       DestinationFiles="@(YourFilesToCopy->'$(YourDestinationDirectory)\%(RecursiveDir)%(Filename)%(Extension)')" /> 
    </Target> 
</Project> 
+0

La tarea 'CreateItem' está en desuso. Regex tiene la alternativa. https://msdn.microsoft.com/en-us/library/s2y3e43x.aspx –

+0

Funcionó perfectamente con VS2015, gracias. – mecek

35

soy un poco nuevo a MSBuild pero encuentro el EXEC de tareas muy útil para situaciones como estas. Encontré el mismo desafío en mi proyecto y esto funcionó para mí y fue mucho más simple. Alguien por favor avíseme si no es una buena práctica.

<Target Name="CopyToDeployFolder" DependsOnTargets="CompileWebSite"> 
    <Exec Command="xcopy.exe $(OutputDirectory) $(DeploymentDirectory) /e" WorkingDirectory="C:\Windows\" /> 
</Target> 
+7

Me atrevo a hacer la pregunta al revés. ¿Hay algún motivo para utilizar la tarea de copia de registro de llenado de msbuild? –

+4

Potencialmente. Si tiene una granja de servidores de compilación (Jenkins, TeamCity, etc.), el servicio de agente puede ejecutarse bajo una cuenta diferente que no tenga xcopy en la ruta. Puedes probar cosas como% windir% \ system32 en la ruta, pero incluso esto no funciona algunas veces. –

+0

Esa es la solución que funcionó para mí. Además, no necesitaba configurar el WorkingDirectory. – Aebsubis

9
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5"> 
    <PropertyGroup> 
     <YourDestinationDirectory>..\SomeDestinationDirectory</YourDestinationDirectory> 
     <YourSourceDirectory>..\SomeSourceDirectory</YourSourceDirectory> 
    </PropertyGroup> 

    <Target Name="BeforeBuild"> 
     <CreateItem Include="$(YourSourceDirectory)\**\*.*"> 
      <Output TaskParameter="Include" ItemName="YourFilesToCopy" /> 
     </CreateItem> 

     <Copy SourceFiles="@(YourFilesToCopy)" 
       DestinationFiles="$(YourFilesToCopy)\%(RecursiveDir)" /> 
    </Target> 
</Project> 

\**\*.* ayuda a obtener los archivos de toda la carpeta. RecursiveDir ayudar a poner todo el archivo en la carpeta respectiva ...

+2

Los archivos de destino se refieren a 1 elementos y los archivos de origen se refieren a 33 elementos. Deben tener la misma cantidad de elementos. Ugh ... msbuild puede ser increíble, pero a veces es una pieza de basura tan mal documentada. –

+0

La tarea 'CreateItem' está en desuso. Regex tiene la alternativa. https://msdn.microsoft.com/en-us/library/s2y3e43x.aspx –

80

Estaba buscando ayuda en esto también. Me tomó un tiempo, pero esto es lo que hice que funcionó muy bien.

<Target Name="AfterBuild"> 
    <ItemGroup> 
     <ANTLR Include="..\Data\antlrcs\**\*.*" /> 
    </ItemGroup> 
    <Copy SourceFiles="@(ANTLR)" DestinationFolder="$(TargetDir)\%(RecursiveDir)" SkipUnchangedFiles="true" /> 
</Target> 

Esta forma recursiva copiar el contenido de la carpeta con el nombre antlrcs a la $(TargetDir).

+4

Sí, esta es la mejor respuesta. Lo mismo que se recomienda aquí en msdn blog: http://blogs.msdn.com/b/msbuild/archive/2005/11/07/490068.aspx – Karsten

+2

Funciona bien, ¡gracias! Me pregunto por qué otras respuestas más complicadas tienen más votos ascendentes? – Ivan

+9

El truco parece ser que al agregar '% (RecursiveDir)' a la carpeta de destino se recreará la estructura del directorio. De lo contrario, la salida es plana. Esta es la mejor respuesta. –

2

Este es el ejemplo que trabajaba:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 

    <ItemGroup> 
     <MySourceFiles Include="c:\MySourceTree\**\*.*"/> 
    </ItemGroup> 

    <Target Name="CopyFiles"> 
     <Copy 
     SourceFiles="@(MySourceFiles)" 
     DestinationFiles="@(MySourceFiles->'c:\MyDestinationTree\%(RecursiveDir)%(Filename)%(Extension)')" 
     /> 
    </Target> 

</Project> 

fuente: https://msdn.microsoft.com/en-us/library/3e54c37h.aspx

0

Esto es tarea de copia que he usado en mi propio proyecto, que estaba trabajando perfectamente para mí esa carpeta copias con las subcarpetas hasta el destino éxito:

<ItemGroup > 
<MyProjectSource Include="$(OutputRoot)/MySource/**/*.*" /> 
</ItemGroup> 

<Target Name="AfterCopy" AfterTargets="WebPublish"> 
<Copy SourceFiles="@(MyProjectSource)" 
OverwriteReadOnlyFiles="true" DestinationFolder="$(PublishFolder)api/% (RecursiveDir)"/> 

En mi caso, copié la carpeta de publicación de un proyecto a otra carpeta de destino, creo que es similar a su caso.

Cuestiones relacionadas