Chcę usunąć wszystkie foldery bin i obj, aby zmusić wszystkie projekty do przebudowania wszystkiego


262

Pracuję z wieloma projektami i chcę rekurencyjnie usunąć wszystkie foldery o nazwie „bin” lub „obj” w ten sposób, jestem pewien, że wszystkie projekty odbudują wszystko (czasami jest to jedyny sposób, aby zmusić Visual Studio do zapomnienia o poprzednich kompilacje).

Czy istnieje szybki sposób na osiągnięcie tego (na przykład za pomocą pliku .bat) bez konieczności pisania programu .NET?


25
Byłoby miło, gdyby Build-> Clean Solution faktycznie to zrobił.
Dustin Andrews,

Odpowiedzi:


411

To zależy od powłoki, której wolisz używać.

Jeśli używasz powłoki cmd w systemie Windows, powinny działać następujące czynności:

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"

Jeśli używasz powłoki typu bash lub zsh (takiej jak git bash lub babun w systemie Windows lub większości powłok Linux / OS X), jest to o wiele ładniejszy, bardziej zwięzły sposób na robienie tego, co chcesz:

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

i można to zredukować do jednej linii za pomocą OR:

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

Zauważ, że jeśli twoje katalogi z nazwami plików zawierają spacje lub cudzysłowy, find wyśle ​​te wpisy bez zmian, które xargs może podzielić na wiele wpisów. Jeśli twoja powłoka je obsługuje -print0i -0obejdzie to niedociągnięcie, więc powyższe przykłady stają się:

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

i:

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

Jeśli używasz programu PowerShell, możesz użyć tego:

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

jak widać poniżej w odpowiedzi Roberta H. - upewnij się, że przypisujesz mu odpowiedź Powerhell, a nie mnie, jeśli zdecydujesz się głosować cokolwiek :)

Mądrze byłoby uruchomić najpierw dowolne polecenie, które wybierzesz w bezpiecznym miejscu, aby je przetestować!


5
dziękuję za odpowiedź. Pojawia się błąd: %% G był w tej chwili nieoczekiwany.
MichaelD

Hmm, to dziwne - działa dobrze na mojej maszynie (vista 64-bitowy biznes) - spróbuję również na maszynie xp.
Steve Willcock

48
„%% G było w tej chwili nieoczekiwane” - dzieje się tak, gdy uruchomisz go z wiersza poleceń zamiast z pliku wsadowego. W tym przypadku użyj pojedynczych „%”.
Designpattern

4
+1 Czy mógłbyś mi wyjaśnić kod? Proszę.
fiberOptics

2
@ SteveWillcock To lepsze niż czyste. Clean nie usunie bibliotek dll, do których nie ma już odniesienia w projekcie (resztki).
Piotr Szmyd

255

Znalazłem ten wątek i dostałem bingo. Trochę więcej poszukiwań ujawniło ten skrypt powłoki:

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

Myślałem, że podzielę się, biorąc pod uwagę, że nie znalazłem odpowiedzi, kiedy tu patrzyłem.


@Nigel, Czy to rozwiązanie nie jest wyjątkowo nieskuteczne? Dlaczego nie napisać niestandardowego skryptu C, który może działać z prędkością 10 razy większą?
Pacerier

37
Nie potrzebujesz foreach - powinieneś po prostu umieść gci bezpośrednio w usuwanym elemencie (tj. gci -include bin,obj -recurse | remove-item -force -recurse)
Chris J

1
Musiałem także wykluczyć foldery z ścieżki wyszukiwania i podoba mi się -WhatIfflaga, aby najpierw przetestować, więc skończyłem z tym: $foldersToRemove='bin','obj';[string[]]$foldersToIgnore='ThirdParty';Get-ChildItem .\ -Include $foldersToRemove -Recurse|Where-Object{$_.FullName -inotmatch "\\$($foldersToIgnore -join '|')\\"}|Remove-Item -Force -Recurse -WhatIf(trochę niechlujny tutaj jako jedna linia :))
Johny Skovdal

@ChrisJ Zastanów się nad dodaniem nowej odpowiedzi do swojego rozwiązania.
granadaCoder

66

To działało dla mnie:

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

Na podstawie tej odpowiedzi na superuser.com


1
Świetny i łatwy do rozszerzenia. Używam dla / d / r. %% d w (bin, obj, App_Data, paczki) czy @if istnieje "%% d" rd / s / q "%% d"
RickAndMSFT

3
@ParoX musisz uruchomić go w pliku .bat
James L

33

Zawsze staram się dodawać nowy cel do moich rozwiązań, aby to osiągnąć.

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

I możesz to nazwać z linii poleceń

msbuild /t:clean_folders

To może być twój plik wsadowy.

msbuild /t:clean_folders
PAUSE

To nie działa w przypadku pliku SLN, ponieważ nie można wywoływać na nim niestandardowych celów lub znasz obejście tego problemu
Piotr Owsiak

3
@PiotrOwsiak tak, musisz utworzyć plik „before.MySlnFileName.sln.targets” w tym samym katalogu, w którym znajduje się plik .sln, i umieścić tam swoje definicje docelowe
Endrju

2
możesz dodać AfterTargets = "Clean" jako atrybut do obiektu docelowego, zostanie on automatycznie wywołany po czyszczeniu, które jest wywoływane bezpośrednio lub pośrednio podczas przebudowy
Newtopian

29

Aby to zrobić, napisałem skrypt PowerShell .

Zaletą jest to, że drukuje podsumowanie usuniętych folderów i ignoruje je, jeśli określono hierarchię podfolderów do zignorowania.

Przykład wyjściowy


1
+1 bardzo fajnie! Właśnie dowiedziałem się, że możemy debugować i zobaczyć zmienne jak debugger z funkcją pełnego pobierania w programie Windows Power Shell!
wiz -_- lee

Podoba mi się to rozwiązanie. Nie muszę zadzierać z Visual Studio i mogę to uruchomić, kiedy chcę. Bardzo dobrze!
Halcyon,

Idealnie odpowiada moim potrzebom, ale nie jestem pewien, dlaczego nie może to być zwykła istota, a nie pełne repozytorium. :-)
Dan Atkinson

Dobra robota! Pominąłbym skanowanie wszystkich katalogów, ponieważ gdy masz tysiące podkatalogów, może to być dość powolne. Zbyt wysoka cena tylko dla statystyk :-). Dodałbym również $_ -notmatch 'node_modules'warunek do $FoldersToRemovedefinicji zmiennej
Tomino

16

Nic mi nie działało. Musiałem usunąć wszystkie pliki z folderów bin i obj w celu debugowania i wydania. Moje rozwiązanie:

1. Kliknij projekt prawym przyciskiem myszy, zwolnij, ponownie kliknij prawym przyciskiem myszy edycję, przejdź do dołu

2. Włóż

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

3. Zapisz, przeładuj projekt, kliknij prawym przyciskiem myszy, wyczyść i presto.


13

Coś takiego powinno zrobić to w dość elegancki sposób, po czystym celu:

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

7

Aby usunąć bin i obj przed kompilacją dodaj do pliku projektu:

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

Oto artykuł: Jak usunąć folder bin i / lub obj przed kompilacją lub wdrożeniem


1
Jednak będziesz chciał to zrobić tylko przy przebudowie. Chyba że chcesz, aby każda kompilacja była przebudową!
Josh M.,

4

Bardzo podobny do skryptów PowerShell Steve'a. Właśnie dodałem TestResults i pakiety, ponieważ jest to potrzebne w większości projektów.

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



3

Bardzo szybkim i bezbolesnym sposobem jest użycie rimrafnarzędzia npm, najpierw zainstaluj go globalnie:

> npm i rimraf -g

A następnie polecenie z katalogu głównego projektu jest dość proste (które można zapisać w pliku skryptu):

projectRoot> rimraf **/bin **/obj

Aby zoptymalizować pożądany efekt, możesz wykorzystać cele zdarzenia projektu (tym, którego możesz użyć, BeforeRebuildi uruchomić poprzednie polecenie), które są określone w dokumentach: https://docs.microsoft.com/en-us/visualstudio/ msbuild / how-to-extension-the-visual-studio-build-process? view = vs-2017

Podoba mi się narzędzie rimraf, ponieważ jest bardzo krzywe i bardzo szybkie. Ale możesz także użyć RemoveDirpolecenia w .csproj, jeśli zdecydujesz się na opcję zdarzenia docelowego. RemoveDirPodejście zostało dobrze wyjaśnione w innym odpowiedź tutaj @Shaman: https://stackoverflow.com/a/22306653/1534753


2

Oto odpowiedź, której udzieliłem na podobne pytanie: proste, łatwe, działa całkiem dobrze i nie wymaga niczego innego niż to, co masz już w Visual Studio.

Gdy inni już odpowiedzieli, Wyczyść usunie wszystkie artefakty generowane przez kompilację. Ale pozostawi po sobie wszystko inne.

Jeśli masz pewne modyfikacje w projekcie MSBuild, może to oznaczać problemy i pozostawić za sobą rzeczy, które Twoim zdaniem powinny zostać usunięte.

Możesz obejść ten problem za pomocą prostej zmiany swojego. * Proj, dodając go gdzieś pod koniec:

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

Co spowoduje usunięcie wszystkiego z folderu bin bieżącej platformy / konfiguracji.


2

To jest mój plik wsadowy, którego używam do rekurencyjnego usuwania wszystkich folderów BIN i OBJ.

  1. Utwórz pusty plik i nazwij go DeleteBinObjFolders.bat
  2. Skopiuj i wklej poniższy kod do DeleteBinObjFolders.bat
  3. Przenieś plik DeleteBinObjFolders.bat do tego samego folderu z plikiem rozwiązania (* .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

Czy „czyste” nie jest wystarczająco dobre? Zauważ, że możesz wywołać msbuild za pomocą / t: clean z wiersza poleceń.


7
Rzeczywiście „czyste” nie jest wystarczająco dobre. Jest to szczególnie prawdziwe w przypadku korzystania z MEF. „Czyste rozwiązanie” nie pozbywa się usuniętych referencji, co może powodować problemy podczas dynamicznego ładowania bibliotek DLL folderu.
Alex

5
Wiele błędów „działa na moim komputerze” jest spowodowanych przez stare lub nieoczekiwane rzeczy siedzące w folderach bin / obj, które nie są usuwane przez „czyste”.
Łukasz

1

Na naszym serwerze kompilacji jawnie usuwamy katalogi bin i obj za pomocą skryptów nant.

Każdy skrypt kompilacji projektu odpowiada za jego katalogi wyjściowe / tymczasowe. Ładnie działa w ten sposób. Kiedy więc zmieniamy projekt i dodajemy nowy, opieramy skrypt na działającym skrypcie, a Ty zauważasz etap usuwania i zajmujesz się nim.

Jeśli robisz to na maszynie do programowania logiki, trzymałbym się czyszczenia za pomocą Visual Studio, jak wspominali inni.


czasami muszę tylko upewnić się, że wszystkie kompilacje są całkowicie nowe. Nie mogę ufać czystemu rozwiązaniu do tego. Usuwanie bin i obj często okazało się bardziej niezawodne
MichaelD

Dla nas tylko kompilacje z „maszyny kompilacji” są testowane lub wykorzystywane w środowisku produkcyjnym, więc programiści nie muszą mieć problemów typu „wszystkie czyste”, a serwer kompilacji to robi. Oznacza to również, że żaden programista nie jest potrzebny do wykonania pełnej wersji.
Simeon Pilgrim

1
Jak najłatwiej to zrobić za pomocą nanta? Mam hierarchię kilkudziesięciu projektów i wolałbym nie odpalić skryptu usuwającego. =)
mpontillo,

Mamy wbudowane wiele plików wykonywalnych / bibliotek dlls, więc na zasób mamy nant skrypt, który go buduje. Dla każdego znajduje się sekcja Usuń, w której umieszczamy wiersz dla każdego katalogu debug / release bin / obj, który chcemy usunąć.
Simeon Pilgrim

1

Nienawidzę plików obj zaśmiecających drzewa źródłowe. Zwykle konfiguruję projekty tak, aby generowały pliki obj poza drzewem źródłowym. W przypadku projektów w języku C # zwykle używam

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

Dla projektów w C ++

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

1

http://vsclean.codeplex.com/

Narzędzie wiersza poleceń, które znajduje rozwiązania Visual Studio i uruchamia na nich polecenie Wyczyść. Pozwala to wyczyścić katalogi / bin / * wszystkich starych projektów, które leżą na twoim dysku twardym


1

Możesz faktycznie pójść dalej z sugestią PS i utworzyć plik vbs w katalogu projektu w następujący sposób:

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

Dla bezpieczeństwa zawarłem parametr -WhatIf, więc usuń go, jeśli lista jest zadowalająca przy pierwszym uruchomieniu.


1

Używam niewielkiej modyfikacji Roberta H, która pomija błędy i drukuje usunięte pliki. I usally również wyczyścić .vs, _resharperi packagefoldery:

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

Warto również zwrócić uwagę na gitpolecenie, które usuwa wszystkie zmiany, w tym ignorowane pliki i katalogi:

git clean -dfx

0

Mamy duże pliki .SLN z wieloma plikami projektów. Założyłem zasadę posiadania katalogu „ViewLocal”, w którym znajdują się wszystkie pliki niekontrolowane przez źródło. Wewnątrz tego katalogu znajduje się katalog „Inter” i „Out”. Odpowiednio dla plików pośrednich i plików wyjściowych.

To oczywiście ułatwia przejście do katalogu „viewlocal” i wykonanie prostego usunięcia, aby się wszystkiego pozbyć.

Zanim poświęcisz czas na znalezienie sposobu obejścia tego problemu za pomocą skryptów, możesz pomyśleć o skonfigurowaniu czegoś podobnego.

Nie będę jednak kłamał, utrzymanie takiej konfiguracji w dużej organizacji okazało się ... interesujące. Zwłaszcza gdy korzystasz z technologii takich jak QT, które lubią przetwarzać pliki i tworzyć pliki źródłowe niekontrolowane przez źródło. Ale to cała INNA historia!


0

Biorąc pod uwagę, że plik PS1 jest obecny w bieżącym folderze (folder, w którym należy usunąć foldery bin i obj)

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

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

0

Do rozwiązania w partii. Używam następującego polecenia:

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


Powód nieużywania DIR /S /AD /B xxx
1. DIR /S /AD /B objzwróci pustą listę (przynajmniej na moim Windows10) 2. będzie zawierać wynik, którego nie należy się spodziewać (folder tobj) wprowadź opis zdjęcia tutaj
DIR /S /AD /B *objwprowadź opis zdjęcia tutaj


@IF EXIST %%G IF %%~aG geq dsłuży do sprawdzania istniejącej ścieżki, a ścieżka jest folderem, a nie plikiem.
xianyi

0

To działa dobrze dla mnie: start dla / d / r. %% d w (bin, obj, ClientBin, Generated_Code) czy @if istnieje "%% d" rd / s / q "%% d"


0

Używam do tego pliku .bat.

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

Myślę, że możesz kliknąć prawym przyciskiem myszy swoje rozwiązanie / projekt i kliknąć przycisk „Wyczyść”.

O ile pamiętam, tak to działało. Nie mam teraz mojego VS.NET, więc nie mogę go przetestować.


Zgadza się i zdecydowanie najprostsze i najłatwiejsze ze wszystkich sugerowanych rozwiązań (zakładając, że jest odpowiednie do konkretnej sytuacji ...)
Chris Halcrow,

8
Przepraszam, ale to po prostu nieprawda. Nie usuwa zawartości katalogu / obj, który jest przyczyną problemu. Przynajmniej taka jest sytuacja z aktualizacją 3 VS 2013
Ognyan Dimitrov

Właśnie miałem ten sam problem z aktualizacją VS2013 4. (Uwaga: VS2010 radził sobie dobrze)
juFo

Zobacz tę odpowiedź (na to samo pytanie), aby uzyskać lepsze wyjaśnienie: stackoverflow.com/a/18317221/374198
Josh M.,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.