2009-05-12 7 views
10

Ho un problema strano con il comportamento di msbuild con un progetto di distribuzione Web VS2008 e vorrei sapere perché sembra comportarsi in modo casuale.Come eliminare più file con il progetto di implementazione di msbuild/web?

Ho bisogno di rimuovere un numero di file da una cartella di distribuzione che dovrebbe esistere solo nel mio ambiente di sviluppo. I file sono stati generati dall'applicazione web durante dev/testing e non sono inclusi nel mio progetto/soluzione di Visual Studio.

La configurazione che sto usando è la seguente:

<!-- 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> 

Il problema che ho è che quando faccio una build/rebuild del progetto Web Deployment che "a volte" rimuove tutti i file ma altre volte non rimuoverà nulla! O rimuoverà solo una o due delle tre cartelle nel gruppo di articoli DeleteAfterBuild. Non sembra esserci coerenza quando il processo di compilazione decide di rimuovere i file o meno.

Quando ho modificato la configurazione per includere solo la cartella 1 (ad esempio), rimuove tutti i file correttamente. Quindi aggiungendo le cartelle 2 e 3, inizia a rimuovere tutti i file come voglio. Quindi, sembrando a caso, ricostruirò il progetto e non rimuoverò nessuno dei file!

Ho provato a spostare questi elementi nel gruppo di oggetti ExcludeFromBuild (che probabilmente è dove dovrebbe essere) ma mi dà lo stesso risultato imprevedibile.

Qualcuno ha provato questo? Sto facendo qualcosa di sbagliato? Perché succede?

risposta

27

Il <ItemGroup> viene valutata quando i carichi di script e prima della <Target> è stato elaborato.

Sembra che ci sia più di un modo per farlo in modo corretto -

  1. Includere il <ItemGroup> all'interno del <Target> e dovrebbero essere valutati al momento giusto. Questo funziona con MS-Costruire v3.5 +

  2. Usa <CreateItem> per generare la lista oggetto

Esempio costruire lo script per questo -

<!-- 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> 

di spiegare perché il processo di cancellazione è stata generazione di risultati "imprevedibili" -

  1. Iniziare con un percorso di uscita di generazione pulita
  2. Build # 1 - crea il progetto di distribuzione Web. @(DeleteAfterBuild) valuterà senza file poiché i file non esistono nella cartella $(OutputPath) e non eliminerà alcun file come parte dell'obiettivo
  3. Build # 2 - crea il progetto di distribuzione Web.@(DeleteAfterBuild) valuterà con tutti i file previsti nella cartella $(OutputPath) e rimuoverà i file come parte dell'obiettivo AfterBuild
  4. Fondamentalmente siamo ora tornati alla fase 2. Ripeti. I risultati sono ovviamente prevedibili - non grattarti più la testa.

Materiale di riferimento: How To: Create Item Groups on the Fly, Delayed evaluation of items in MSBUILD file

+0

+1 - Avevo lo stesso identico grattacapo. Questa è stata una risposta perfetta. Grazie! – spot

0

Mi rendo conto che questo è già stato risposto, ma ho pensato di aggiungere i miei 5 centesimi. Per un progetto di distribuzione Web non è necessario utilizzare gli obiettivi forniti, è sufficiente aggiungere un gruppo di articoli contenente gli elementi ExcludeFromBuild. Ho fornito la sezione pertinente dalla parte inferiore del mio file di progetto di implementazione come riferimento.

<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> 
Problemi correlati