.net - microsoft - msbuild que es
¿Por qué MSBuild no copia como yo esperaría? (4)
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 de SourceDir se define así:
<ItemGroup>
<SourceDir Include="$(Source)/**/*" />
<SourceDir Include="E:/ExternalDependencies/**/*" />
<SourceDir Include="//sharedlibraries/gdiplus/*.h" />
</ItemGroup>
¿Cómo se vería el árbol de la carpeta de destino?
Para conservar el árbol, debe hacer una transformación de identidad y generar un elemento de destino para cada elemento en la colección SourceFiles. Aquí hay un ejemplo:
<Copy SourceFiles="@(Compile)" DestinationFiles="@(Compile->''$(DropPath)%(Identity)'')" />
La tarea Copiar tomará cada elemento de la colección SourceFiles y transformará su ruta reemplazando la parte antes de ** en la especificación del elemento de origen con $ (DropPath).
Se podría argumentar que la propiedad DestinationFolder debería haberse escrito como un acceso directo a la siguiente transformación:
<Copy SourceFiles="@(Compile)" DestinationFiles="@(Compile->''$(DestinationFolder)%(Identity)'')" />
Por desgracia, eso evitaría el escenario de copia profunda a carpeta plana que está intentando evitar, pero otras personas podrían usar en su proceso de compilación.
Necesito guiar mi compilación. 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?
Aquí están las partes relacionadas de mi script de compilación:
<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>
Encontré el ejemplo en uno de los ejemplos en MSDN . No lo entiendo pero dejaré un ejemplo para mis compañeros de viaje aquí en . Aquí está la versión fija del objetivo migrate de arriba:
<Target Name="migrate" DependsOnTargets="Clean">
<Copy DestinationFiles="@(SourceDir->''$(DeployPath)/%(RecursiveDir)%(Filename)%(Extension)'')" SourceFiles="@(SourceDir)" />
</Target>
Si alguien realmente entiende este ejemplo, por favor explique. ¡Buena suerte!
Solo una joya que encontramos mientras depuramos los problemas de MSBuild en torno a la copia:
http://blog.scrappydog.com/2008/06/subtle-msbuild-bug-feature.html
Los grupos de elementos se analizan antes que los objetivos, por lo que los objetivos que crean archivos nuevos (por ejemplo, ¡compila!) No se recogerán cuando se haga referencia a un grupo de artículos a lo largo del guión.
Eric Bowen también describe una solución alternativa para esta "característica", la tarea CreateItem :
<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 para él!
Ejemplo muy simple que copia los contenidos y la estructura de un directorio recursivamente:
<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 al igual que xcopy.