2009-05-12 12 views
10

Tengo un problema extraño con la forma en que se está comportando msbuild con un proyecto de implementación web VS2008 y me gustaría saber por qué parece comportarse mal al azar.Cómo eliminar varios archivos con el proyecto de despliegue web/msbuild?

Necesito eliminar una cantidad de archivos de una carpeta de implementación que solo debería existir en mi entorno de desarrollo. Los archivos han sido generados por la aplicación web durante el desarrollo/prueba y no están incluidos en mi proyecto/solución de Visual Studio.

La configuración que estoy usando es el siguiente:

<!-- Partial extract from Microsoft Visual Studio 2008 Web Deployment Project --> 
<ItemGroup> 
    <DeleteAfterBuild Include="$(OutputPath)data\errors\*.xml" /> <!-- Folder 1: 36 files --> 
    <DeleteAfterBuild Include="$(OutputPath)data\logos\*.*" /> <!-- Folder 2: 2 files --> 
    <DeleteAfterBuild Include="$(OutputPath)banners\*.*" />  <!-- Folder 3: 1 file --> 
</ItemGroup> 

<Target Name="AfterBuild"> 
    <Message Text="------ AfterBuild process starting ------" Importance="high" /> 
    <Delete Files="@(DeleteAfterBuild)"> 
     <Output TaskParameter="DeletedFiles" PropertyName="deleted" /> 
    </Delete> 
    <Message Text="DELETED FILES: $(deleted)" Importance="high" /> 
    <Message Text="------ AfterBuild process complete ------" Importance="high" /> 
</Target> 

El problema que tengo es que cuando hago una construcción/reconstrucción del Proyecto de Desarrollo de Web que "a veces" elimina todos los archivos pero otras veces no eliminará nada! O eliminará solo una o dos de las tres carpetas en el grupo de elementos DeleteAfterBuild. Parece que no hay consistencia en cuando el proceso de compilación decide eliminar los archivos o no.

Cuando edité la configuración para incluir solo la Carpeta 1 (por ejemplo), elimina todos los archivos correctamente. Luego, agregando la Carpeta 2 y 3, comienza a eliminar todos los archivos como yo quiera. ¡Entonces, pareciendo en momentos aleatorios, reconstruiré el proyecto y no eliminará ninguno de los archivos!

He intentado mover estos elementos al grupo de elementos ExcludeFromBuild (que probablemente sea donde debería estar) pero me da el mismo resultado impredecible.

¿Alguien ha experimentado esto? ¿Estoy haciendo algo mal? ¿Por qué pasó esto?

Respuesta

27

El <ItemGroup> se evalúa cuando se carga el script y antes de la <Target> ha sido procesado.

Parece que hay más de una manera de hacer esto correctamente -

  1. Incluir el <ItemGroup> interior de la <Target> y que deben ser evaluados en el momento correcto. Esto funciona con la versión 3.5 de MS-Build +

  2. Uso <CreateItem> para generar la lista de elementos

Ejemplo Creación de un script para esto -

<!-- Using ItemGroup --> 
<Target Name="AfterBuild"> 
    <ItemGroup> 
    <DeleteAfterBuild Include="$(OutputPath)data\errors\*.xml" /> 
    </ItemGroup> 
    <Delete Files="@(DeleteAfterBuild)" /> 
</Target> 

<!-- Using CreateItem --> 
<Target Name="AfterBuild"> 
    <CreateItem Include="$(OutputPath)data\errors\*.xml"> 
    <Output TaskParameter="Include" ItemName="DeleteAfterBuild"/> 
    </CreateItem> 
    <Delete Files="@(DeleteAfterBuild)" /> 
</Target> 

explicar por qué el proceso de borrado era generando resultados 'impredecibles' -

  1. Comience con una ruta de salida de construcción limpia
  2. Build # 1: compile el proyecto de implementación web. @(DeleteAfterBuild) evaluará sin archivos, ya que los archivos no existen en la carpeta $(OutputPath) y no eliminará ningún archivo como parte del objetivo AfterBuild
  3. Build # 2 - build the Web Deployment Project.@(DeleteAfterBuild) evaluará con todos los archivos esperados en la carpeta $(OutputPath) y eliminará los archivos como parte del objetivo AfterBuild
  4. Básicamente, volvemos a la etapa 2. Repita. Los resultados son, por supuesto, predecibles, ya no te rasques la cabeza.

Material de referencia: How To: Create Item Groups on the Fly, Delayed evaluation of items in MSBUILD file

+0

+1 - Tenía exactamente el mismo rasguño en la cabeza. Esta fue una respuesta perfecta. ¡Gracias! – spot

0

Me di cuenta que ya ha sido contestada pero pensé que me gustaría añadir mis 5 centavos. Para un proyecto de implementación web no es necesario utilizar los objetivos proporcionados, solo agregue un grupo de elementos que contenga ExcludeFromBuild elementos. Proporcioné la sección relevante de la parte inferior del archivo de proyecto de implementación como referencia.

<Import Project="$(MSBuildExtensionsPath)\Microsoft\WebDeployment\v9.0\Microsoft.WebDeployment.targets" /> 
    <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
     Other similar extension points exist, see Microsoft.WebDeployment.targets. 
    <Target Name="BeforeBuild"> 
    </Target> 
    <Target Name="BeforeMerge"> 
    </Target> 
    <Target Name="AfterMerge"> 
    </Target> 
    <Target Name="AfterBuild"> 
    </Target> 
    --> 
    <ItemGroup> 
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\obj\**\*.*" /> 
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\Properties\**\*.*" /> 
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\**\*.csproj*" /> 
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\**\*.resx" /> 
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\**\*.Publish.xml" /> 
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\LocalTestRun.testrunconfig" /> 
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\TestResults\**\*.*" /> 
    </ItemGroup> 
Cuestiones relacionadas