Voglio eliminare tutte le cartelle bin e obj per forzare tutti i progetti a ricostruire tutto


263

Lavoro con più progetti e desidero eliminare in modo ricorsivo tutte le cartelle con il nome 'bin' o 'obj' in questo modo, sono sicuro che tutti i progetti ricostruiranno tutto (a volte è l'unico modo per costringere Visual Studio a dimenticare tutto ciò che è stato precedentemente costruisce).

Esiste un modo rapido per ottenere questo risultato (ad esempio con un file .bat) senza dover scrivere un programma .NET?


25
Sarebbe bello se Build-> Clean Solution lo facesse davvero.
Dustin Andrews,

Risposte:


412

Questo dipende dalla shell che preferisci usare.

Se si utilizza la shell cmd su Windows, dovrebbe funzionare quanto segue:

FOR /F "tokens=*" %%G IN ('DIR /B /AD /S bin') DO RMDIR /S /Q "%%G"
FOR /F "tokens=*" %%G IN ('DIR /B /AD /S obj') DO RMDIR /S /Q "%%G"

Se stai usando una shell di tipo bash o zsh (come git bash o babun su Windows o la maggior parte delle shell di Linux / OS X), questo è un modo molto più semplice e succinto di fare quello che vuoi:

find . -iname "bin" | xargs rm -rf
find . -iname "obj" | xargs rm -rf

e questo può essere ridotto a una riga con un OR:

find . -iname "bin" -o -iname "obj" | xargs rm -rf

Nota che se le tue directory di nomi di file contengono spazi o virgolette, find invierà tali voci così come sono, che gli xarg possono dividere in più voci. Se la shell li supporta -print0e -0risolverà questo problema, gli esempi precedenti diventano:

find . -iname "bin" -print0 | xargs -0 rm -rf
find . -iname "obj" -print0 | xargs -0 rm -rf

e:

find . -iname "bin" -o -iname "obj" -print0 | xargs -0 rm -rf

Se si utilizza Powershell, è possibile utilizzare questo:

Get-ChildItem .\ -include bin,obj -Recurse | foreach ($_) { remove-item $_.fullname -Force -Recurse }

come si vede nella risposta di Robert H qui sotto - assicurati di dargli credito per la risposta PowerShell piuttosto che per me se scegli di votare qualcosa :)

Naturalmente sarebbe saggio eseguire qualsiasi comando scegliate prima in un luogo sicuro per testarlo!


5
grazie per la tua risposta. Ricevo un errore: %% G era inaspettato in questo momento.
MichaelD,

Hmm è strano - funziona benissimo sulla mia macchina (vista a 64 bit) - Lo proverò anche su una macchina xp.
Steve Willcock,

48
"%% G era imprevisto in questo momento" - questo accade quando lo si esegue dalla riga di comando anziché all'interno di un file batch. Usa '%' singolo in questo caso.
Designpattern,

4
+1 Ti dispiacerebbe spiegarmi il codice? Per favore.
fibre ottiche

2
@SteveWillcock È meglio che pulito. Clean non rimuoverà più le DLL a cui non si fa più riferimento nel progetto (rimanenze).
Piotr Szmyd,

256

Ho trovato questa discussione e ho ottenuto il bingo. Un po 'più di ricerca ha rivelato questo script Power Shell:

Get-ChildItem .\ -include bin,obj -Recurse | ForEach-Object ($_) { Remove-Item $_.FullName -Force -Recurse }

Ho pensato di condividere, considerando che non ho trovato la risposta quando stavo guardando qui.


@Nigel, questa soluzione non è estremamente performante? Perché non scrivere uno script C personalizzato che può essere eseguito a una velocità 10 volte superiore?
Pacerier

37
Non hai bisogno del foreach - dovresti essere in grado di reindirizzare gci direttamente in remove-item (cioè, gci -include bin,obj -recurse | remove-item -force -recurse)
Chris J

1
Avevo bisogno di escludere anche le cartelle dal percorso di ricerca e mi piace -WhatIfprima testare la bandiera, quindi ho finito con questo: $foldersToRemove='bin','obj';[string[]]$foldersToIgnore='ThirdParty';Get-ChildItem .\ -Include $foldersToRemove -Recurse|Where-Object{$_.FullName -inotmatch "\\$($foldersToIgnore -join '|')\\"}|Remove-Item -Force -Recurse -WhatIf(un po 'disordinato qui come una riga però :))
Johny Skovdal

@ChrisJ Valuta di aggiungere una nuova risposta con la tua soluzione.
granadaCoder

66

Questo ha funzionato per me:

for /d /r . %%d in (bin,obj) do @if exist "%%d" rd /s/q "%%d"

Sulla base di questa risposta su superuser.com


1
Fantastico e facile da estendere. Uso per / d / r. %% d in (bin, obj, App_Data, pacchetti) se @ esiste "%% d" rd / s / q "%% d"
RickAndMSFT

3
@ParoX devi eseguirlo all'interno di un file .bat
James L

33

Uso sempre un nuovo obiettivo nelle mie soluzioni per raggiungere questo obiettivo.

<Target Name="clean_folders">
  <RemoveDir Directories=".\ProjectName\bin" />
  <RemoveDir Directories=".\ProjectName\obj" />
  <RemoveDir Directories="$(ProjectVarName)\bin" />
  <RemoveDir Directories="$(ProjectVarName)\obj" />
</Target>

E puoi chiamarlo dalla riga di comando

msbuild /t:clean_folders

Questo può essere il tuo file batch.

msbuild /t:clean_folders
PAUSE

Questo non funziona per un file sln poiché non è possibile richiamare obiettivi personalizzati su di essi o si conosce una soluzione alternativa per questo
Piotr Owsiak,

3
@PiotrOwsiak sì, devi creare il file "before.MySlnFileName.sln.targets" nella stessa directory in cui hai il tuo .sln e inserisci le tue definizioni di destinazione
Endrju

2
puoi aggiungere AfterTargets = "Clean" come attributo al Target, verrà automaticamente chiamato dopo il Clean che viene richiamato direttamente o indirettamente quando si esegue una ricostruzione
Newtopian

29

Ho scritto uno script PowerShell per farlo.

Il vantaggio è che stampa un riepilogo delle cartelle eliminate e di quelle ignorate se si specifica una gerarchia di sottocartelle da ignorare.

Esempio di output


1
+1 molto bello! Ho appena scoperto che possiamo effettivamente eseguire il debug e vedere le variabili come un debugger a recupero completo in Window Power Shell!
wiz -_- lee

Mi piace questa soluzione. Non devo scherzare con Visual Studio e posso eseguirlo quando voglio. Molto bella!
Halcyon,

Si adatta perfettamente alle mie esigenze, ma non sono sicuro del motivo per cui questo non potrebbe essere un riassunto piuttosto che un repository completo. :-)
Dan Atkinson il

Bel lavoro! Ometterei la scansione di tutte le directory perché quando hai migliaia di sottodirectory, questo potrebbe essere piuttosto lento. Prezzo troppo alto solo per le statistiche :-). Inoltre aggiungerei la $_ -notmatch 'node_modules'condizione alla $FoldersToRemovedefinizione della variabile
Tomino

16

Niente ha funzionato per me. Avevo bisogno di eliminare tutti i file nelle cartelle bin e obj per il debug e il rilascio. La mia soluzione:

1.Fare clic con il pulsante destro del mouse sul progetto, scaricare, fare nuovamente clic con il pulsante destro del mouse, andare in fondo

2.Insert

<Target Name="DeleteBinObjFolders" BeforeTargets="Clean">
  <RemoveDir Directories="..\..\Publish" />
  <RemoveDir Directories=".\bin" />
  <RemoveDir Directories="$(BaseIntermediateOutputPath)" />
</Target>

3. Salva, ricarica il progetto, fai clic con il pulsante destro del mouse su clean e presto.


13

Qualcosa del genere dovrebbe farlo in un modo abbastanza elegante, dopo un obiettivo pulito:

<Target Name="RemoveObjAndBin" AfterTargets="Clean">
    <RemoveDir Directories="$(BaseIntermediateOutputPath)" />
    <RemoveDir Directories="$(TargetDir)" />
</Target>

7

Per eliminare bin e obj prima di compilare aggiungi al file di progetto:

<Target Name="BeforeBuild">
    <!-- Remove obj folder -->
    <RemoveDir Directories="$(BaseIntermediateOutputPath)" />
    <!-- Remove bin folder -->
    <RemoveDir Directories="$(BaseOutputPath)" />
</Target>

Ecco l'articolo: Come rimuovere bin e / o obj folder prima della compilazione o della distribuzione


1
Tuttavia, ti consigliamo di farlo solo su una ricostruzione. A meno che tu non voglia che ogni build sia una ricostruzione!
Josh M.,

4

Molto simile agli script di Steve PowerShell. Ho appena aggiunto TestResults e pacchetti in quanto è necessario per la maggior parte dei progetti.

Get-ChildItem .\ -include bin,obj,packages,TestResults -Recurse | foreach ($_) { remove-item $_.fullname -Force -Recurse }



3

Un modo molto rapido e indolore è usare l' rimrafutility npm, installarla prima a livello globale:

> npm i rimraf -g

E quindi il comando dalla radice del progetto è abbastanza semplice (che può essere salvato in un file di script):

projectRoot> rimraf **/bin **/obj

Per ottimizzare l'effetto desiderato puoi sfruttare gli obiettivi dell'evento del progetto (quello che potresti usare è BeforeRebuilde farlo eseguire il comando precedente) che sono specificati nei documenti: https://docs.microsoft.com/en-us/visualstudio/ msbuild / how-to-extend-the-visual-studio-build-processo? view = vs-2017

Mi piace l'utilità rimraf in quanto è crossplat e molto veloce. Tuttavia, puoi anche utilizzare il RemoveDircomando in .csproj se decidi di utilizzare l'opzione evento target. L' RemoveDirapproccio è stato ben spiegato in un'altra risposta qui da @Shaman: https://stackoverflow.com/a/22306653/1534753


2

Ecco la risposta che ho dato a una domanda simile, semplice, facile, funziona abbastanza bene e non richiede nient'altro che quello che hai già con Visual Studio.

Come altri hanno già risposto, Clean rimuoverà tutti gli artefatti generati dalla build. Ma lascerà tutto il resto.

Se hai alcune personalizzazioni nel tuo progetto MSBuild, questo potrebbe significare problemi e lasciare cose che penseresti che avrebbero dovuto eliminare.

Puoi aggirare questo problema con una semplice modifica al tuo. * Proj aggiungendolo da qualche parte verso la fine:

<Target Name="SpicNSpan"
        AfterTargets="Clean">
    <RemoveDir Directories="$(OUTDIR)"/>
</Target>

Che rimuoverà tutto nella cartella bin della piattaforma / configurazione corrente.


2

Questo è il mio file batch che utilizzo per eliminare ricorsivamente tutte le cartelle BIN e OBJ.

  1. Crea un file vuoto e chiamalo DeleteBinObjFolders.bat
  2. Copia e incolla il codice seguente in DeleteBinObjFolders.bat
  3. Spostare il file DeleteBinObjFolders.bat nella stessa cartella con il file della soluzione (* .sln).
@echo off
@echo Deleting all BIN and OBJ folders...
for /d /r . %%d in (bin,obj) do @if exist "%%d" rd /s/q "%%d"
@echo BIN and OBJ folders successfully deleted :) Close the window.
pause > nul

1

'Pulito' non è abbastanza buono? Nota che puoi chiamare msbuild con / t: clean dalla riga di comando.


7
In effetti "pulito" non è abbastanza buono. Ciò è particolarmente vero quando si utilizza MEF. "Soluzione pulita" non elimina i riferimenti rimossi che possono causare problemi durante il caricamento dinamico delle DLL di una cartella.
Alex,

5
Molti bug di "funziona sulla mia macchina" sono causati da cose vecchie o impreviste che si trovano nelle cartelle bin / obj che non vengono rimosse facendo un "clean".
Luca,

1

Sul nostro server di build, eliminiamo esplicitamente le directory bin e obj, tramite script nant.

Ogni script di compilazione del progetto è responsabile delle sue directory output / temp. Funziona bene in questo modo. Quindi quando cambiamo un progetto e ne aggiungiamo uno nuovo, basiamo lo script su uno script funzionante e notate la fase di eliminazione e ne prendete cura.

Se lo fai sulla tua macchina per lo sviluppo della logica, mi limiterei a pulire tramite Visual Studio come altri hanno già detto.


a volte devo solo essere sicuro che tutte le build siano completamente nuove. Non posso fidarmi di una soluzione pulita per farlo. La cancellazione di bin e obj si è spesso dimostrata più affidabile
MichaelD

Per noi, solo i build dalla "macchina build" sono testati o utilizzati in produzione, quindi gli sviluppatori non devono avere problemi di tipo "tutto pulito", e il server build lo fa. Significa anche che nessuno sviluppatore è necessario per creare una build completa.
Simeon Pilgrim,

1
Qual è il modo più semplice per farlo con nant? Ho una gerarchia di un paio di dozzine di progetti e preferirei non sbagliare su uno script di eliminazione. =)
mpontillo,

Abbiamo molti 'asset' eseguibili / dlls costruiti, quindi per asset abbiamo uno script nant che lo costruisce. Per ognuno c'è una sezione Elimina in cui inseriamo una riga per ogni directory bin / obj di debug / release che vogliamo eliminare.
Simeon Pilgrim,

1

In realtà odio i file obj che sporcano gli alberi dei sorgenti. Di solito installo i progetti in modo che emettano file obj all'esterno dell'albero dei sorgenti. Per i progetti C # di solito uso

 <IntermediateOutputPath>..\..\obj\$(AssemblyName)\$(Configuration)\</IntermediateOutputPath>

Per progetti C ++

 IntermediateDirectory="..\..\obj\$(ProjectName)\$(ConfigurationName)"

1

http://vsclean.codeplex.com/

Strumento da riga di comando che trova le soluzioni di Visual Studio ed esegue il comando Clean su di esse. Questo ti consente di ripulire le directory / bin / * di tutti quei vecchi progetti che hai in giro sul tuo hard disk


1

In realtà potresti prendere un po 'di più il suggerimento di PS e creare un file vbs nella directory del progetto in questo modo:

Option Explicit
Dim oShell, appCmd
Set oShell  = CreateObject("WScript.Shell")
appCmd      = "powershell -noexit Get-ChildItem .\ -include bin,obj -Recurse | foreach ($_) { remove-item $_.fullname -Force -Recurse -WhatIf }"
oShell.Run appCmd, 4, false

Per sicurezza, ho incluso il parametro -WhatIf, quindi rimuovilo se sei soddisfatto dell'elenco al primo avvio.


1

Uso una leggera modifica di Robert H che salta gli errori e stampa i file eliminati. Ho eseguirne anche chiaro i .vs, _resharpere le packagecartelle:

Get-ChildItem -include bin,obj,packages,'_ReSharper.Caches','.vs' -Force -Recurse | foreach ($_) { remove-item $_.fullname -Force -Recurse -ErrorAction SilentlyContinue -Verbose}

Vale anche la pena notare il gitcomando che cancella tutte le modifiche inclusi i file e le directory ignorati:

git clean -dfx

0

Abbiamo un grande file .SLN con molti file di progetto. Ho iniziato la politica di avere una directory "ViewLocal" in cui si trovano tutti i file non controllati da fonti. All'interno di quella directory c'è una 'Inter' e una 'Out'. Per i file intermedi e i file di output, rispettivamente.

Questo ovviamente rende semplice accedere alla directory 'viewlocal' ed eseguire una semplice eliminazione per sbarazzarsi di tutto.

Prima di dedicare del tempo a trovare un modo per aggirare questo problema con gli script, potresti pensare di creare qualcosa di simile.

Non mentirò però, mantenere un simile setup in una grande organizzazione si è rivelato ... interessante. Soprattutto quando si utilizzano tecnologie come QT che amano elaborare i file e creare file di origine non controllati da fonti. Ma questa è tutta un'altra storia!


0

Considerando che il file PS1 è presente nella cartella corrente (la cartella in cui è necessario eliminare le cartelle bin e obj)

$currentPath = $MyInvocation.MyCommand.Path
$currentFolder = Split-Path $currentPath

Get-ChildItem $currentFolder -include bin,obj -Recurse | foreach ($_) { remove-item $_.fullname -Force -Recurse }

0

Per la soluzione in batch. Sto usando il seguente comando:

FOR /D /R %%G in (obj,bin) DO @IF EXIST %%G IF %%~aG geq d RMDIR /S /Q "%%G"


Il motivo per cui non si utilizza DIR /S /AD /B xxx
1. DIR /S /AD /B objverrà restituito un elenco vuoto (almeno sul mio Windows 10) 2. conterrà il risultato non previsto (cartella tobj) inserisci qui la descrizione dell'immagine
DIR /S /AD /B *objinserisci qui la descrizione dell'immagine


@IF EXIST %%G IF %%~aG geq dviene utilizzato per controllare il percorso esistente e il percorso è una cartella non un file.
Xianyi,

0

Funziona benissimo per me: inizia per / d / r. %% d in (bin, obj, ClientBin, Generated_Code) se @ esiste "%% d" rd / s / q "%% d"


0

Per farlo uso il file .bat con questo comando.

for /f %%F in ('dir /b /ad /s ^| findstr /iles "Bin"') do RMDIR /s /q "%%F"
for /f %%F in ('dir /b /ad /s ^| findstr /iles "Obj"') do RMDIR /s /q "%%F"

-1

Penso che puoi fare clic con il tasto destro sulla soluzione / progetto e fare clic sul pulsante "Pulisci".

Per quanto ricordo, funzionava così. Non ho il mio VS.NET con me ora, quindi non posso provarlo.


Esatto, e di gran lunga la più semplice e la più semplice di tutte le soluzioni suggerite (supponendo che sia appropriata alla situazione specifica ....)
Chris Halcrow

8
Siamo spiacenti, ma questo non è semplicemente vero. Non elimina i contenuti di / obj che sono la radice del problema. Almeno questa è la situazione con VS 2013 aggiornamento 3.
Ognyan Dimitrov,

Ho appena avuto lo stesso problema con l'aggiornamento VS2013 4. (Nota: VS2010 stava andando bene)
juFo

Vedi questa risposta (su questa stessa domanda) per una spiegazione migliore: stackoverflow.com/a/18317221/374198
Josh M.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.