Je veux supprimer tous les dossiers bin et obj pour forcer tous les projets à tout reconstruire

263

Je travaille avec plusieurs projets et je veux supprimer récursivement tous les dossiers portant le nom «bin» ou «obj» de cette façon, je suis sûr que tous les projets reconstruiront tout (parfois c'est le seul moyen de forcer Visual Studio à tout oublier sur les précédents) builds).

Existe-t-il un moyen rapide d'accomplir cela (avec un fichier .bat par exemple) sans avoir à écrire un programme .NET?

MichaelD
la source
25
Ce serait bien si Build-> Clean Solution faisait cela.
Dustin Andrews,

Réponses:

412

Cela dépend du shell que vous préférez utiliser.

Si vous utilisez le shell cmd sous Windows, les éléments suivants devraient fonctionner:

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"

Si vous utilisez un shell de type bash ou zsh (comme git bash ou babun sous Windows ou la plupart des shells Linux / OS X), c'est une manière beaucoup plus agréable et plus succincte de faire ce que vous voulez:

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

et cela peut être réduit à une ligne avec un OU:

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

Notez que si vos répertoires de noms de fichiers contiennent des espaces ou des guillemets, find enverra ces entrées telles quelles, que les xargs peuvent diviser en plusieurs entrées. Si votre shell les prend en charge -print0et -0contournera cette lacune, les exemples ci-dessus deviennent:

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

et:

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

Si vous utilisez Powershell, vous pouvez utiliser ceci:

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

comme on le voit dans la réponse de Robert H ci - dessous - assurez-vous de lui donner le crédit pour la réponse PowerShell plutôt que moi si vous choisissez de voter pour quelque chose :)

Il serait bien sûr judicieux d'exécuter la commande que vous choisissez dans un endroit sûr pour la tester!

Steve Willcock
la source
5
merci pour votre réponse. Je reçois une erreur: %% G était inattendu pour le moment.
MichaelD
Hmm c'est bizarre - ça marche bien sur ma machine (vista 64bit business) - Je vais aussi l'essayer sur une machine xp.
Steve Willcock
48
"%% G était inattendu pour le moment" - cela se produit lorsque vous l'exécutez à partir de la ligne de commande plutôt qu'à l'intérieur d'un fichier de commandes. Utilisez des «%» uniques dans ce cas.
Designpattern
4
+1 Pourriez-vous m'expliquer le code? S'il vous plaît.
fibreOptics
2
@SteveWillcock C'est mieux que propre. Clean ne supprimera plus les DLL qui ne sont plus référencées dans le projet (restes).
Piotr Szmyd
256

J'ai trouvé ce fil et obtenu le bingo. Un peu plus de recherche a révélé ce script Power Shell:

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

J'ai pensé partager, considérant que je n'ai pas trouvé la réponse quand je regardais ici.

Robert H.
la source
@ Nigel, cette solution n'est-elle pas extrêmement peu performante? Pourquoi ne pas écrire un script C personnalisé pouvant fonctionner à 10 fois la vitesse?
Pacerier
37
Vous n'avez pas besoin de foreach - vous devriez simplement pouvoir diriger gci directement dans remove-item (ie, gci -include bin,obj -recurse | remove-item -force -recurse)
Chris J
1
J'avais également besoin d'exclure des dossiers du chemin de recherche, et j'aime que le -WhatIfdrapeau teste d'abord, alors je me suis retrouvé avec ceci: $foldersToRemove='bin','obj';[string[]]$foldersToIgnore='ThirdParty';Get-ChildItem .\ -Include $foldersToRemove -Recurse|Where-Object{$_.FullName -inotmatch "\\$($foldersToIgnore -join '|')\\"}|Remove-Item -Force -Recurse -WhatIf(un peu compliqué ici en une seule ligne :))
Johny Skovdal
@ChrisJ Envisagez d'ajouter une nouvelle réponse à votre solution.
granadaCoder
66

Cela a fonctionné pour moi:

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

Basé sur cette réponse sur superuser.com

Daniel Rehner
la source
1
Génial et facile à étendre. J'utilise pour / d / r. %% d dans (bin, obj, App_Data, packages) existe-t-il si "%% d" rd / s / q "%% d"
RickAndMSFT
3
@ParoX vous devez l'exécuter dans un fichier .bat
James L
33

J'utilise pour toujours ajouter un nouvel objectif sur mes solutions pour y parvenir.

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

Et vous pouvez l'appeler à partir de la ligne de commande

msbuild /t:clean_folders

Cela peut être votre fichier batch.

msbuild /t:clean_folders
PAUSE
Jhonny D. Cano -Leftware-
la source
Cela ne fonctionne pas pour un fichier sln car vous ne pouvez pas appeler des cibles personnalisées sur eux ou connaissez-vous une solution pour cela
Piotr Owsiak
3
@PiotrOwsiak oui, vous devez créer le fichier "before.MySlnFileName.sln.targets" dans le même répertoire où vous avez votre .sln et y mettre vos définitions cibles
Endrju
2
vous pouvez ajouter AfterTargets = "Clean" en tant qu'attribut à la cible, il sera automatiquement appelé après le Clean qui est appelé directement ou indirectement lors d'une reconstruction
Newtopian
29

J'ai écrit un script PowerShell pour le faire.

L'avantage est qu'il imprime un résumé des dossiers supprimés et des dossiers ignorés si vous avez spécifié une hiérarchie de sous-dossiers à ignorer.

Exemple de sortie

doblak
la source
1
+1 très sympa! Je viens de découvrir que nous pouvons réellement déboguer et voir les variables comme un débogueur à extraction complète dans Window Power Shell!
wiz -_- lee
J'aime cette solution. Je n'ai pas à jouer avec Visual Studio et je peux l'exécuter quand je veux. Très agréable!
Halcyon
Convient parfaitement à mes besoins, mais je ne sais pas pourquoi cela ne pourrait pas être un résumé plutôt qu'un repo complet. :-)
Dan Atkinson
Bon travail! J'omettre l'analyse de tous les répertoires car lorsque vous avez des milliers de sous-répertoires, cela peut être assez lent. Prix ​​trop élevé juste pour les statistiques :-). J'ajouterais également une $_ -notmatch 'node_modules'condition à la $FoldersToRemovedéfinition de variable
Tomino
16

Rien n'a fonctionné pour moi. J'avais besoin de supprimer tous les fichiers des dossiers bin et obj pour le débogage et la publication. Ma solution:

1.Cliquez avec le bouton droit sur le projet, déchargez, cliquez de nouveau avec le bouton droit de la souris, allez en bas

2. insérez

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

3. Enregistrez, rechargez le projet, cliquez avec le bouton droit sur Clean et presto.

Kdefthog
la source
13

Quelque chose comme ça devrait le faire d'une manière assez élégante, après une cible propre:

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

Pour supprimer bin et obj avant la construction, ajoutez au fichier de projet:

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

Voici l'article: Comment supprimer le dossier bin et / ou obj avant la génération ou le déploiement

Chaman
la source
1
Cependant, vous ne voudrez le faire que lors d'une reconstruction. À moins que vous ne vouliez que chaque build soit une reconstruction!
Josh M.
4

Très similaire aux scripts PowerShell de Steve. Je viens d'y ajouter TestResults et des packages car cela est nécessaire pour la plupart des projets.

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

Jetez un œil au CleanProject , il supprimera les dossiers bin, les dossiers obj, les dossiers TestResults et les dossiers Resharper. Le code source est également disponible.

habakuk
la source
Le projet semble s'être déplacé ici: code.msdn.microsoft.com/windowsdesktop/…
Johny Skovdal
3

Un moyen très rapide et indolore consiste à utiliser l' rimrafutilitaire npm, à l'installer globalement en premier:

> npm i rimraf -g

Et puis la commande de la racine de votre projet est assez simple (qui peut être enregistrée dans un fichier de script):

projectRoot> rimraf **/bin **/obj

Pour optimiser l'effet souhaité, vous pouvez tirer parti des cibles d'événements du projet (celle que vous pouvez utiliser est BeforeRebuildet lui faire exécuter la commande précédente) qui sont spécifiées dans les documents: https://docs.microsoft.com/en-us/visualstudio/ msbuild / comment-étendre-le-processus-de-construction-de-visual-studio? view = vs-2017

J'aime l'utilitaire rimraf car il est crossplat et très rapide. Mais, vous pouvez également utiliser la RemoveDircommande dans le .csproj si vous décidez d'utiliser l'option d'événement cible. L' RemoveDirapproche a été bien expliquée dans une autre réponse ici par @Shaman: https://stackoverflow.com/a/22306653/1534753

Vedran Mandić
la source
2

Voici la réponse que j'ai donnée à une question similaire, Simple, facile, fonctionne assez bien et ne nécessite rien d'autre que ce que vous avez déjà avec Visual Studio.

Comme d'autres ont déjà répondu, Clean supprimera tous les artefacts générés par la génération. Mais cela laissera tout le reste.

Si vous avez des personnalisations dans votre projet MSBuild, cela pourrait causer des problèmes et laisser des éléments que vous penseriez qu'il aurait dû supprimer.

Vous pouvez contourner ce problème en modifiant simplement votre projet. * En ajoutant ceci quelque part vers la fin:

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

Ce qui supprimera tout dans votre dossier bin de la plate-forme / configuration actuelle.

Newtopian
la source
2

Il s'agit de mon fichier de commandes que j'utilise pour supprimer tous les dossiers BIN et OBJ de manière récursive.

  1. Créez un fichier vide et nommez-le DeleteBinObjFolders.bat
  2. Copiez-collez le code ci-dessous dans le DeleteBinObjFolders.bat
  3. Déplacez le fichier DeleteBinObjFolders.bat dans le même dossier avec votre fichier de solution (* .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
Alper Ebicoglu
la source
1

«Propre» n'est-il pas assez bon? Notez que vous pouvez appeler msbuild avec / t: clean à partir de la ligne de commande.

Brian
la source
7
En effet "propre" n'est pas suffisant. Cela est particulièrement vrai lors de l'utilisation de MEF. "Clean Solution" ne supprime pas les références que vous avez supprimées, ce qui peut entraîner des problèmes lors du chargement dynamique des DLL d'un dossier.
Alex
5
Beaucoup de bugs "fonctionne sur ma machine" sont causés par des trucs anciens ou inattendus qui traînent dans les dossiers bin / obj qui ne sont pas supprimés en faisant un "nettoyage".
Luke
1

Sur notre serveur de build, nous supprimons explicitement les répertoires bin et obj, via des scripts nant.

Chaque script de construction de projet est responsable de ses répertoires de sortie / temp. Fonctionne bien de cette façon. Ainsi, lorsque nous modifions un projet et en ajoutons un nouveau, nous basons le script sur un script de travail, et vous remarquez l'étape de suppression et vous en occupez.

Si vous le faites sur votre machine de développement logique, je m'en tiendrai au nettoyage via Visual Studio comme d'autres l'ont mentionné.

Simeon Pilgrim
la source
Parfois, je dois juste être sûr que toutes les versions sont complètement nouvelles. Je ne peux pas faire confiance à une solution propre pour faire ça. La suppression de bin et obj s'est souvent révélée plus fiable
MichaelD
Pour nous, seules les versions de la `` machine de génération '' sont testées ou utilisées en production, de sorte que les développeurs ne doivent pas avoir de problèmes de type `` tout propre '', et le serveur de génération le fait. Cela signifie également qu'aucun développeur n'est nécessaire pour créer une version complète.
Simeon Pilgrim
1
Quelle est la façon la plus simple de le faire avec nant? J'ai une hiérarchie de quelques dizaines de projets et je préfère ne pas raté un script de suppression. =)
mpontillo
Nous avons de nombreux actifs exécutables / DLL construits, donc par actif nous avons un script nant qui le construit. Pour chacun, il y a une section Supprimer où nous plaçons une ligne pour chaque répertoire debug / release bin / obj que nous voulons supprimer.
Simeon Pilgrim
1

Je déteste en fait les fichiers obj qui jonchent les arbres sources. J'ai l'habitude de configurer des projets pour qu'ils produisent des fichiers obj en dehors de l'arborescence source. Pour les projets C # que j'utilise habituellement

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

Pour les projets C ++

 IntermediateDirectory="..\..\obj\$(ProjectName)\$(ConfigurationName)"
Juozas Kontvainis
la source
1

http://vsclean.codeplex.com/

Outil de ligne de commande qui trouve des solutions Visual Studio et exécute la commande Clean sur elles. Cela vous permet de nettoyer les répertoires / bin / * de tous les anciens projets que vous avez sur votre disque dur

Joel Martinez
la source
1

Vous pouvez en fait pousser la suggestion PS un peu plus loin et créer un fichier vbs dans le répertoire du projet comme ceci:

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

Pour des raisons de sécurité, j'ai inclus le paramètre -WhatIf, donc supprimez-le si vous êtes satisfait de la liste lors de la première exécution.

KL XL
la source
1

J'utilise une légère modification de Robert H qui saute les erreurs et imprime les fichiers supprimés. Je usally aussi clair que les .vs, _resharperet les packagedossiers:

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

Il convient également de noter la gitcommande qui efface toutes les modifications, y compris les fichiers et répertoires ignorés:

git clean -dfx
eugstman
la source
0

Nous avons un gros fichier .SLN avec de nombreux fichiers de projet. J'ai commencé la politique d'avoir un répertoire "ViewLocal" où se trouvent tous les fichiers non contrôlés par la source. À l'intérieur de ce répertoire se trouve un répertoire «Inter» et «Out». Pour les fichiers intermédiaires et les fichiers de sortie, respectivement.

Évidemment, il est facile d'aller simplement dans votre répertoire 'viewlocal' et de faire une simple suppression, pour vous débarrasser de tout.

Avant de passer du temps à trouver un moyen de contourner ce problème avec les scripts, vous pourriez penser à configurer quelque chose de similaire.

Je ne mentirai pas cependant, le maintien d'une telle configuration dans une grande organisation s'est révélé ... intéressant. Surtout lorsque vous utilisez des technologies telles que QT qui aiment traiter des fichiers et créer des fichiers source non contrôlés par des sources. Mais c'est toute une AUTRE histoire!

pj4533
la source
0

Considérant que le fichier PS1 est présent dans le dossier actuel (le dossier dans lequel vous devez supprimer les dossiers bin et obj)

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

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

Pour la solution en batch. J'utilise la commande suivante:

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


La raison de ne pas utiliser DIR /S /AD /B xxx
1. DIR /S /AD /B objretournera une liste vide (au moins sur mon Windows10) 2. contiendra le résultat qui n'est pas attendu (dossier tobj) entrez la description de l'image ici
DIR /S /AD /B *objentrez la description de l'image ici

xianyi
la source
@IF EXIST %%G IF %%~aG geq dest utilisé pour vérifier le chemin existant et le chemin est un dossier et non un fichier.
xianyi
0

Cela fonctionne bien pour moi: commencez pour / d / r. %% d dans (bin, obj, ClientBin, Generated_Code) existe-t-il si "%% d" rd / s / q "%% d"

Mudit Sharma
la source
0

J'utilise le fichier .bat avec cette commande pour ce faire.

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"
Hacko
la source
-1

Je pense que vous pouvez cliquer avec le bouton droit sur votre solution / projet et cliquer sur le bouton "Nettoyer".

Pour autant que je m'en souvienne, ça fonctionnait comme ça. Je n'ai pas mon VS.NET avec moi maintenant, je ne peux donc pas le tester.

dr. mal
la source
C'est exact, et de loin la solution la plus simple et la plus facile de toutes les solutions suggérées (en supposant qu'elle est appropriée à la situation spécifique ....)
Chris Halcrow
8
Désolé, mais ce n'est tout simplement pas vrai. Il ne supprime pas le contenu de / obj qui est à l'origine du problème. C'est du moins la situation avec la mise à jour VS 2013 3.
Ognyan Dimitrov
Juste eu le même problème avec la mise à jour VS2013 4. (Remarque: VS2010 allait bien)
juFo
Voir cette réponse (sur cette même question) pour une meilleure explication: stackoverflow.com/a/18317221/374198
Josh M.