2008-11-05 12 views
7

Necesito script my build. Estoy usando MSBUILD debido a su integración con VS.net. Estoy intentando copiar algunos archivos del entorno de compilación a la carpeta de implementación. Estoy usando la tarea de copiar de MSBuild. Pero en lugar de copiar el árbol de directorios como era de esperar. copia todos los contenidos en una sola carpeta. Repito todos los archivos del árbol de directorios terminan en una carpeta. Lo necesito para copiar el árbol de carpetas y directorios en la carpeta de destino. ¿Se me escapa algo?¿Por qué no copia MSBuild como era de esperar?

Aquí es las partes relavant de mi escritura de la estructura:

<PropertyGroup> 
    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion> 
    <Source>outputfolder</Source> 
    <DestEnv>x</DestEnv> 
    <DeployPath>\\networkpath\$(DestEnv)</DeployPath> 
</PropertyGroup> 
<ItemGroup> 
    <TargetDir Include="$(DeployPath)\**\*" Exclude="**\web.config"></TargetDir> 
    <SourceDir Include="$(Source)\**\*" /> 
</ItemGroup>  
<Target Name="Clean" > 
    <!-- clean detail ... --> 
</Target> 
<Target Name="migrate" DependsOnTargets="Clean"> 
    <Copy DestinationFolder="$(DeployPath)" SourceFiles="@(SourceDir)" /> 
</Target> 

Respuesta

4

me encontré con el ejemplo de uno de los ejemplos en MSDN que no entiendo, pero dejaré un ejemplo para mis compañeros travelers aquí en stackoverflow . Aquí está la versión fija del destino de migración desde arriba:

<Target Name="migrate" DependsOnTargets="Clean"> 
    <Copy DestinationFiles="@(SourceDir->'$(DeployPath)\%(RecursiveDir)%(Filename)%(Extension)')" SourceFiles="@(SourceDir)" /> 
</Target> 

Si alguien realmente entiende este ejemplo, explique. ¡Buena suerte!

12

Cuando especifica DestinationFolder para la tarea Copiar, toma todos los elementos de la colección SourceFiles y los copia en DestinationFolder. Se espera esto, ya que no hay forma de que la tarea Copiar resuelva qué parte de la ruta de cada elemento debe reemplazarse con DestinationFolder para mantener la estructura del árbol. Por ejemplo, si su colección SourceDir se define así:

<ItemGroup> 
    <SourceDir Include="$(Source)\**\*" /> 
    <SourceDir Include="E:\ExternalDependencies\**\*" /> 
    <SourceDir Include="\\sharedlibraries\gdiplus\*.h" /> 
</ItemGroup> 

¿Cómo se esperaría que fuera el árbol de la carpeta de destino?

Para conservar el árbol, debe realizar una transformación de identidad y generar un elemento de destino para cada elemento en la colección SourceFiles. He aquí un ejemplo:

<Copy SourceFiles="@(Compile)" DestinationFiles="@(Compile->'$(DropPath)%(Identity)')" /> 

tarea de copia El tomará la cada elemento de la colección sourcefiles, y transformará su camino mediante la sustitución de la parte antes del ** en la especificación elemento de origen con $ (DropPath).

Se podría argumentar que la propiedad DestinationFolder debería haber sido escrito como un acceso directo a la siguiente transformación:

<Copy SourceFiles="@(Compile)" DestinationFiles="@(Compile->'$(DestinationFolder)%(Identity)')" /> 

Ay, que impida la copia en profundidad de escenario carpeta normal que usted está tratando de evitar, pero otras personas podrían usar en su proceso de construcción.

5

Ejemplo muy simple que copia un contenido y la estructura de directorios de forma recursiva:

<Copy SourceFiles="@(Compile)" DestinationFolder="c:\foocopy\%(Compile.RecursiveDir)"></Copy> 

@ (Compilar) es un ItemGroup de todos los archivos que desea copiar. Podría ser algo así como:

<ItemGroup> 
     <Compile Include=".\**\*.dll" /> 
    </ItemGroup> 

La tarea Copiar copiará todos los archivos en c: \ foocopy igual que xcopy.

+0

da el error: MSBUILD: error MSB4095: El elemento de metadatos% (RecursiveDir) se está haciendo referencia sin una nombre del árticulo. Especifique el nombre del elemento usando% (itemname.RecursiveDir). –

+0

No tengo ni idea de qué está pasando –

+1

debería haber reparado el error ... sintaxis alternativa para el valor de DestinationFolder: DestinationFolder = "@ (Compilar -> 'c: \ foocopy \% (RecursiveDir)')" – Adam

13

Sólo una joya que encontramos como estábamos depuración de problemas de MSBuild alrededor de copiado:

http://blog.scrappydog.com/2008/06/subtle-msbuild-bug-feature.html

ItemGroups son analizadas antes de Blancos, por lo que cualquier blanco que crean nuevos archivos (por ejemplo compila!) no se recogerá cuando se haga referencia a un ItemGroup más adelante a lo largo del script.

Eric Bowen también describe un trabajo en torno a esta "característica", el CreateItem tarea:

<Target Name="Copy" > 
    <CreateItem Include="..\Source\**\bin\**\*.exe" 
     Exclude="..\Source\**\bin\**\*.vshost.exe"> 
     <Output TaskParameter="Include" ItemName="CompileOutput" /> 
    </CreateItem> 
    <Copy SourceFiles="@(CompileOutput)" 
     DestinationFolder="$(OutputDirectory)"></Copy> 
</Target> 

Muchas felicitaciones a él!

Cuestiones relacionadas