Ich möchte alle bin- und obj-Ordner löschen, um alle Projekte zu zwingen, alles neu zu erstellen


261

Ich arbeite mit mehreren Projekten und möchte alle Ordner mit dem Namen 'bin' oder 'obj' rekursiv löschen. Auf diese Weise bin ich sicher, dass alle Projekte alles neu erstellen (manchmal ist dies die einzige Möglichkeit, Visual Studio zu zwingen, alle vorherigen zu vergessen baut).

Gibt es eine schnelle Möglichkeit, dies zu erreichen (z. B. mit einer .bat-Datei), ohne ein .NET-Programm schreiben zu müssen?


25
Es wäre schön, wenn Build-> Clean Solution dies tatsächlich tun würde.
Dustin Andrews

Antworten:


410

Dies hängt von der Shell ab, die Sie bevorzugen.

Wenn Sie die Cmd-Shell unter Windows verwenden, sollte Folgendes funktionieren:

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"

Wenn Sie eine Shell vom Typ bash oder zsh verwenden (z. B. git bash oder babun unter Windows oder den meisten Linux / OS X-Shells), ist dies eine viel schönere und prägnantere Methode, um das zu tun, was Sie wollen:

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

und dies kann mit einem ODER auf eine Zeile reduziert werden:

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

Beachten Sie, dass find Ihre Einträge unverändert sendet, wenn Ihre Dateinamenverzeichnisse Leerzeichen oder Anführungszeichen enthalten. Xargs kann in mehrere Einträge aufgeteilt werden. Wenn Ihre Shell sie unterstützt -print0und -0dieses Manko umgeht, werden die obigen Beispiele wie folgt:

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

und:

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

Wenn Sie Powershell verwenden, können Sie Folgendes verwenden:

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

Wie in der Antwort von Robert H unten zu sehen - stellen Sie sicher, dass Sie ihm die Powershell-Antwort und nicht mir zuschreiben, wenn Sie sich dafür entscheiden, etwas zu verbessern :)

Es wäre natürlich ratsam, jeden Befehl, den Sie auswählen, zuerst an einem sicheren Ort auszuführen, um ihn zu testen!


5
Danke für deine Antwort. Ich erhalte eine Fehlermeldung: %% G war zu diesem Zeitpunkt unerwartet.
MichaelD

Hmm das ist seltsam - es funktioniert gut auf meinem Computer (Vista 64bit Business) - ich werde es auch auf einem XP-Computer versuchen.
Steve Willcock

48
"%% G war zu diesem Zeitpunkt unerwartet" - Dies geschieht, wenn Sie es über die Befehlszeile anstatt aus einer Batchdatei ausführen. Verwenden Sie in diesem Fall einzelne '%'.
Designmuster

4
+1 Würde es Ihnen etwas ausmachen, mir den Code zu erklären? Bitte.
FiberOptics

2
@SteveWillcock Es ist besser als sauber. Clean entfernt keine DLLs mehr, auf die im Projekt nicht mehr verwiesen wird (Reste).
Piotr Szmyd

255

Ich habe diesen Thread gefunden und Bingo bekommen. Ein bisschen mehr Suchen ergab dieses Power-Shell-Skript:

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

Ich dachte, ich würde teilen, wenn man bedenkt, dass ich die Antwort nicht gefunden habe, als ich hier gesucht habe.


@Nigel, ist diese Lösung nicht extrem leistungsschwach? Warum nicht ein benutzerdefiniertes C-Skript schreiben, das mit der 10-fachen Geschwindigkeit ausgeführt werden kann?
Pacerier

37
Sie brauchen das foreach nicht - Sie sollten in der Lage sein, gci direkt in remove-item (dh gci -include bin,obj -recurse | remove-item -force -recurse) zu leiten
Chris J

1
Ich musste auch Ordner vom Suchpfad ausschließen, und ich möchte, dass die -WhatIfFlagge zuerst getestet wird, also kam ich zu folgendem $foldersToRemove='bin','obj';[string[]]$foldersToIgnore='ThirdParty';Get-ChildItem .\ -Include $foldersToRemove -Recurse|Where-Object{$_.FullName -inotmatch "\\$($foldersToIgnore -join '|')\\"}|Remove-Item -Force -Recurse -WhatIf
Ergebnis

@ChrisJ Erwägen Sie, Ihrer Lösung eine neue Antwort hinzuzufügen.
GranadaCoder

66

Das hat bei mir funktioniert:

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

Basierend auf dieser Antwort auf superuser.com


1
Großartig und einfach zu erweitern. Ich benutze für / d / r. %% d in (bin, obj, App_Data, Pakete) do @if exist "%% d" rd / s / q "%% d"
RickAndMSFT

3
@ParoX müssen Sie es in einer .bat-Datei ausführen
James L

33

Ich füge meinen Lösungen immer ein neues Ziel hinzu, um dies zu erreichen.

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

Und Sie können es von der Kommandozeile aus aufrufen

msbuild /t:clean_folders

Dies kann Ihre Batch-Datei sein.

msbuild /t:clean_folders
PAUSE

Dies funktioniert nicht für eine SLN-Datei, da Sie keine benutzerdefinierten Ziele aufrufen können oder eine Problemumgehung dafür kennen
Piotr Owsiak

3
@PiotrOwsiak Ja, Sie müssen die Datei "before.MySlnFileName.sln.targets" in demselben Verzeichnis erstellen, in dem Sie Ihre .sln haben, und dort Ihre Zieldefinitionen
ablegen

2
Sie können AfterTargets = "Clean" als Attribut zum Ziel hinzufügen. Es wird automatisch nach dem Clean aufgerufen, das direkt oder indirekt beim Wiederherstellen aufgerufen wird
Newtopian

29

Ich habe dazu ein Powershell-Skript geschrieben .

Der Vorteil besteht darin, dass eine Zusammenfassung der gelöschten und ignorierten Ordner gedruckt wird, wenn Sie eine Unterordnerhierarchie angegeben haben, die ignoriert werden soll.

Ausgabebeispiel


1
+1 sehr schön! Wir haben gerade herausgefunden, dass wir die Variablen tatsächlich debuggen und sehen können wie ein Full-Fetch-Debugger in Window Power Shell!
Wiz -_- Lee

Ich mag diese Lösung. Ich muss mich nicht mit Visual Studio anlegen und kann dies ausführen, wenn ich möchte. Sehr schön!
Halcyon

Passt perfekt zu meinen Bedürfnissen, aber ich bin mir nicht sicher, warum dies nicht das Wesentliche sein kann, sondern ein ausgewachsenes Repo. :-)
Dan Atkinson

Gute Arbeit! Ich würde das Scannen aller Verzeichnisse weglassen, da dies bei Tausenden von Unterverzeichnissen sehr langsam sein kann. Zu hoher Preis nur für Statistiken :-). Auch würde ich $_ -notmatch 'node_modules'Bedingung zur $FoldersToRemoveVariablendefinition hinzufügen
Tomino

16

Bei mir hat nichts funktioniert. Ich musste alle Dateien in den Ordnern bin und obj löschen, um sie zu debuggen und freizugeben. Meine Lösung:

1. Klicken Sie mit der rechten Maustaste auf Projekt, entladen Sie, klicken Sie erneut mit der rechten Maustaste auf Bearbeiten und gehen Sie nach unten

2. Einfügen

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

3. Speichern Sie das Projekt, laden Sie es erneut, klicken Sie mit der rechten Maustaste auf Clean und Presto.


13

So etwas sollte es nach einem sauberen Ziel auf ziemlich elegante Weise tun:

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

7

So löschen Sie bin und obj vor dem Erstellen zur Projektdatei:

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

Hier ist der Artikel: So entfernen Sie den Ordner bin und / oder obj vor dem Erstellen oder Bereitstellen


1
Sie möchten dies jedoch nur bei einem Umbau tun. Es sei denn, Sie möchten, dass jeder Build neu erstellt wird!
Josh M.

4

Sehr ähnlich zu Steves PowerShell-Skripten. Ich habe gerade TestResults und Pakete hinzugefügt, da dies für die meisten Projekte erforderlich ist.

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



3

Eine sehr schnelle und schmerzlose Möglichkeit besteht darin, das rimrafDienstprogramm npm zu verwenden und es zuerst global zu installieren:

> npm i rimraf -g

Und dann ist der Befehl von Ihrem Projektstamm ganz einfach (der in einer Skriptdatei gespeichert werden kann):

projectRoot> rimraf **/bin **/obj

Um den gewünschten Effekt zu optimieren, können Sie die Projektereignisziele (die Sie verwenden können BeforeRebuild, um den vorherigen Befehl auszuführen) nutzen, die in den Dokumenten angegeben sind: https://docs.microsoft.com/en-us/visualstudio/ msbuild / How-to-Extend-the-Visual-Studio-Build-Prozess? view = vs-2017

Ich mag das Rimraf-Dienstprogramm, da es plattformübergreifend und sehr schnell ist. Sie können den RemoveDirBefehl jedoch auch in der .csproj-Datei verwenden, wenn Sie sich für die Zielereignisoption entscheiden. Der RemoveDirAnsatz wurde in einer anderen Antwort von @Shaman gut erklärt: https://stackoverflow.com/a/22306653/1534753


2

Hier ist die Antwort ich auf eine ähnliche Frage gegeben habe: Einfach, einfach, funktioniert ziemlich gut und erfordert nichts anderes als das, was Sie bereits mit Visual Studio haben.

Da andere bereits geantwortet haben, entfernt Clean alle Artefakte, die vom Build generiert werden. Aber es wird alles andere zurücklassen.

Wenn Sie einige Anpassungen in Ihrem MSBuild-Projekt vorgenommen haben, kann dies zu Problemen führen und Dinge hinterlassen, von denen Sie denken, dass sie gelöscht werden sollten.

Sie können dieses Problem mit einer einfachen Änderung an Ihrem. * Proj umgehen, indem Sie dies irgendwo gegen Ende hinzufügen:

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

Dadurch wird alles in Ihrem bin-Ordner der aktuellen Plattform / Konfiguration entfernt.


2

Dies ist meine Batch-Datei, mit der ich alle BIN- und OBJ-Ordner rekursiv lösche.

  1. Erstellen Sie eine leere Datei und nennen Sie sie DeleteBinObjFolders.bat
  2. Kopieren Sie den folgenden Code und fügen Sie ihn in die Datei DeleteBinObjFolders.bat ein
  3. Verschieben Sie die Datei DeleteBinObjFolders.bat in denselben Ordner wie Ihre Lösungsdatei (* .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

Ist "sauber" nicht gut genug? Beachten Sie, dass Sie msbuild mit / t: clean über die Befehlszeile aufrufen können.


7
In der Tat ist "sauber" nicht gut genug. Dies gilt insbesondere bei Verwendung von MEF. "Clean Solution" entfernt keine Referenzen, die Sie entfernt haben. Dies kann zu Problemen beim dynamischen Laden der DLLs eines Ordners führen.
Alex

5
Viele "Arbeiten auf meinem Computer" -Fehler werden durch alte oder unerwartete Dinge verursacht, die in den Ordnern "bin / obj" herumliegen und nicht durch "Bereinigen" entfernt werden.
Luke

1

Auf unserem Build-Server löschen wir die Verzeichnisse bin und obj explizit über nant-Skripte.

Jedes Projekterstellungsskript ist für seine Ausgabe- / temporären Verzeichnisse verantwortlich. Funktioniert gut so. Wenn wir also ein Projekt ändern und ein neues hinzufügen, stützen wir das Skript auf ein funktionierendes Skript, und Sie bemerken die Löschphase und kümmern sich darum.

Wenn Sie dies auf Ihrem Logikentwicklungscomputer tun, würde ich mich daran halten, über Visual Studio zu bereinigen, wie andere bereits erwähnt haben.


Manchmal muss ich nur sicher sein, dass alle Builds komplett neu sind. Ich kann einer sauberen Lösung dafür nicht vertrauen. Das Löschen von bin und obj hat sich oft als zuverlässiger erwiesen
MichaelD

Für uns werden nur Builds von der 'Build-Maschine' getestet oder in der Produktion verwendet, sodass die Entwickler keine Probleme vom Typ 'All Clean' haben müssen, und der Build-Server tut dies. Dies bedeutet auch, dass kein Entwickler benötigt wird, um einen vollständigen Build zu erstellen.
Simeon Pilgrim

1
Was ist der einfachste Weg, dies mit nant zu tun? Ich habe eine Hierarchie von ein paar Dutzend Projekten und möchte bei einem Löschskript lieber keine Fehlzündungen auslösen. =)
mpontillo

Wir haben viele ausführbare Dateien / DLLs 'Asset' erstellt, daher haben wir pro Asset ein Nant-Skript, das es erstellt. Für jeden gibt es einen Löschabschnitt, in dem wir eine Zeile für jedes Debug- / Release-Bin / Obj-Verzeichnis einfügen, das gelöscht werden soll.
Simeon Pilgrim

1

Ich hasse eigentlich obj-Dateien, die die Quellbäume verunreinigen. Normalerweise richte ich Projekte so ein, dass sie obj-Dateien außerhalb des Quellbaums ausgeben. Für C # -Projekte verwende ich normalerweise

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

Für C ++ - Projekte

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

1

http://vsclean.codeplex.com/

Befehlszeilentool, das Visual Studio-Lösungen findet und den Befehl Clean auf diesen ausführt. Auf diese Weise können Sie die Verzeichnisse / bin / * aller alten Projekte bereinigen, die auf Ihrer Festplatte herumliegen


1

Sie könnten den PS-Vorschlag sogar etwas weiter gehen und eine vbs-Datei im Projektverzeichnis wie folgt erstellen:

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

Aus Sicherheitsgründen habe ich den Parameter -WhatIf eingefügt. Entfernen Sie ihn daher, wenn Sie mit der Liste beim ersten Durchlauf zufrieden sind.


1

Ich verwende eine geringfügige Modifikation von Robert H, die Fehler überspringt und die Löschdateien druckt. Mir klar usally auch .vs, _resharperund packageOrdner:

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

Erwähnenswert ist auch der gitBefehl, mit dem alle Änderungen einschließlich ignorierter Dateien und Verzeichnisse gelöscht werden:

git clean -dfx

0

Wir haben eine große SLN-Datei mit vielen Projektdateien. Ich habe mit der Richtlinie begonnen, ein "ViewLocal" -Verzeichnis zu haben, in dem sich alle nicht quellengesteuerten Dateien befinden. In diesem Verzeichnis befinden sich ein 'Inter'- und ein' Out'-Verzeichnis. Für die Zwischendateien bzw. die Ausgabedateien.

Dies macht es natürlich einfach, einfach in Ihr 'viewlocal'-Verzeichnis zu gehen und einen einfachen Löschvorgang durchzuführen, um alles loszuwerden.

Bevor Sie sich Gedanken darüber gemacht haben, wie Sie dies mit Skripten umgehen können, sollten Sie sich überlegen, etwas Ähnliches einzurichten.

Ich werde jedoch nicht lügen, die Aufrechterhaltung eines solchen Aufbaus in einer großen Organisation hat sich als ... interessant erwiesen. Besonders wenn Sie Technologien wie QT verwenden, die gerne Dateien verarbeiten und nicht quellengesteuerte Quelldateien erstellen. Aber das ist eine ganz andere Geschichte!


0

Berücksichtigen Sie, dass die PS1-Datei im aktuellen Ordner vorhanden ist (der Ordner, in dem Sie die Ordner bin und obj löschen müssen).

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

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

0

Für die Lösung im Batch. Ich benutze den folgenden Befehl:

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


Der Grund, warum DIR /S /AD /B xxx
1. nicht verwendet DIR /S /AD /B objwird, gibt eine leere Liste zurück (zumindest unter Windows 10 ). 2. enthält das Ergebnis, das nicht erwartet wird (tobj-Ordner). Geben Sie hier die Bildbeschreibung ein
DIR /S /AD /B *objGeben Sie hier die Bildbeschreibung ein


@IF EXIST %%G IF %%~aG geq dwird zum Überprüfen des vorhandenen Pfads verwendet und der Pfad ist ein Ordner, keine Datei.
Xianyi

0

Dies funktioniert gut für mich: Starten Sie für / d / r. %% d in (bin, obj, ClientBin, Generated_Code) ist @if vorhanden "%% d" rd / s / q "%% d"


0

Ich benutze dazu die .bat-Datei mit diesem Kommando.

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

Ich denke, Sie können mit der rechten Maustaste auf Ihre Lösung / Ihr Projekt klicken und auf die Schaltfläche "Reinigen" klicken.

Soweit ich mich erinnere, hat es so funktioniert. Ich habe mein VS.NET jetzt nicht bei mir und kann es daher nicht testen.


Das ist richtig und bei weitem die einfachste und einfachste aller vorgeschlagenen Lösungen (vorausgesetzt, es ist für die spezifische Situation angemessen ...)
Chris Halcrow

8
Sorry, aber das stimmt einfach nicht. Der Inhalt von / obj, der die Ursache des Problems darstellt, wird nicht gelöscht. Zumindest ist dies die Situation mit VS 2013 Update 3.
Ognyan Dimitrov

Hatte gerade das gleiche Problem mit VS2013 Update 4. (Hinweis: VS2010 lief gut)
JuFo

Siehe diese Antwort (auf genau diese Frage) für eine bessere Erklärung: stackoverflow.com/a/18317221/374198
Josh M.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.