Я хочу видалити всі папки bin та obj, щоб змусити всі проекти відновити все


262

Я працюю з декількома проектами, і хочу рекурсивно видаляти всі папки з іменем 'bin' або 'obj' таким чином, я впевнений, що всі проекти відновлять усе (іноді це єдиний спосіб змусити Visual Studio забути все про попередні будує).

Чи є швидкий спосіб досягти цього (наприклад, з файлом .bat) без необхідності писати програму .NET?


25
Було б добре, якби Build-> Clean Solution насправді зробив це.
Дастін Ендрюс

Відповіді:


411

Це залежить від оболонки, яку ви бажаєте використовувати.

Якщо ви використовуєте оболонку cmd в Windows, то слід працювати наступне:

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"

Якщо ви використовуєте оболонку типу bash або zsh (наприклад, git bash або babun в Windows або більшості оболонок Linux / OS X), це набагато приємніший і більш лаконічний спосіб робити те, що ви хочете:

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

і це може бути зменшено до одного рядка за допомогою АБО:

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

Зауважте, що якщо у ваших каталогах імен файлів містяться пробіли або лапки, функція find надішле такі записи такими як є, які xargs можуть розділитись на кілька записів. Якщо ваша оболонка підтримує їх -print0і -0обійде цей короткочасний, то наведені вище приклади стають:

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

і:

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

Якщо ви використовуєте Powershell, ви можете використовувати це:

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

як видно з відповіді Роберта Н нижче - просто переконайтеся, що ви віддаєте йому кредит за відповідь повноважень, а не я, якщо ви вирішите щось голосувати :)

Звичайно, було б розумно запустити будь-яку команду, яку ви оберете десь безпечну, щоб перевірити її!


5
THX для вашої відповіді. Я отримую помилку: %% G наразі несподівано
MichaelD

Хм, це дивно - він чудово працює на моїй машині (Vista 64bit business) - я спробую це і на xp-машині.
Стів Віллок

48
"%% G в цей час був несподіваним" - це відбувається, коли ви запускаєте його з командного рядка, а не з внутрішнього файлу. У цьому випадку використовуйте одиночний '%' s.
Дизайнпатерн

4
+1 Ви б не хотіли пояснити код для мене? Будь ласка.
fiberOptics

2
@SteveWillcock Це краще, ніж чисто. Очищення не видалить клітини, на які більше не посилаються в проекті (залишки).
Пьотр Шмид

255

Я знайшов цю нитку і отримав бінго. Трохи більше пошуку виявило цей сценарій оболонки живлення:

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

Я думав, що поділюсь, вважаючи, що не знайшов відповіді, коли шукав тут.


@Nigel, Хіба це рішення не є надзвичайно ефективним? Чому б не написати користувальницький сценарій С, який може працювати з швидкістю 10 разів?
Pacerier

37
Вам не потрібен передбачення - ви повинні просто мати можливість передавати gci прямо в delete-item (тобто gci -include bin,obj -recurse | remove-item -force -recurse)
Chris J

1
Мені потрібно було також виключити папки з пошукової доріжки, і мені подобається, що -WhatIfпрапор спочатку перевіряється, тому я закінчив це: $foldersToRemove='bin','obj';[string[]]$foldersToIgnore='ThirdParty';Get-ChildItem .\ -Include $foldersToRemove -Recurse|Where-Object{$_.FullName -inotmatch "\\$($foldersToIgnore -join '|')\\"}|Remove-Item -Force -Recurse -WhatIf(хоч трохи тут брудно, як один рядок :))
Джонні Сковдал

@ChrisJ Подумайте про додавання нової відповіді до свого рішення.
granadaCoder

66

Це працювало для мене:

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

Виходячи з цієї відповіді на superuser.com


1
Чудово, і легко розширити. Я використовую для / d / r. %% d (bin, obj, App_Data, пакети) зробіть @if існують "%% d" rd / s / q "%% d"
RickAndMSFT

3
@ParoX вам потрібно запустити його у файлі .bat
Джеймс Л

33

Я завжди використовую нову ціль для своїх рішень для досягнення цього.

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

І ви можете викликати це з командного рядка

msbuild /t:clean_folders

Це може бути ваш пакетний файл.

msbuild /t:clean_folders
PAUSE

Це не працює для файлу sln, оскільки ви не можете зателефонувати на власні цілі на них або знаєте їх вирішення
Piotr Owsiak

3
@PiotrOwsiak так, вам потрібно створити файл "before.MySlnFileName.sln.targets" у тому самому каталозі, де ви маєте свій .sln, і помістіть туди свої цільові визначення
Endrju

2
ви можете додати AfterTargets = "Очистити" як атрибут Цілі, він буде автоматично викликаний після "Очищення", яке викликається прямо чи опосередковано при перебудові
Newtopian

29

Я написав скрипт для оболонки повноважень, щоб це зробити.

Перевага полягає в тому, що він видає резюме видалених папок та ігноруються, якщо ви вказали будь-яку ієрархію підпапок, яку слід ігнорувати.

Вихідний приклад


1
+1 дуже приємно! Щойно з’ясували, що ми можемо налагодити та побачити такі змінні, як повноцінний налагоджувач у вікні Power Shell!
wiz -_- lee

Мені подобається це рішення. Мені не доводиться возитися з Visual Studio, і я можу це запускати, коли хочу. Дуже хороша!
Хелсіон

Цілком відповідає моїм потребам, але я не впевнений, чому це не могло бути не сутью, а не повною репо. :-)
Ден Аткінсон

Хороша робота! Я б пропустив сканування всіх каталогів, тому що, коли у вас є тисячі підкаталогів, це може бути досить повільним. Занадто висока ціна лише для статистики :-). Також я б додав $_ -notmatch 'node_modules'умову до $FoldersToRemoveзмінного визначення
Томіно

16

Ніщо не працювало для мене. Мені потрібно було видалити всі файли в папках bin та obj для налагодження та випуску. Моє рішення:

1. Правий клацання проекту, розвантажте, правою кнопкою миші знову відредагуйте, перейдіть до низу

2.Вступ

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

3. Зберегти, перезавантажити проект, натиснути правою кнопкою миші очистити та встановити попередньо.


13

Щось подібне повинно робити це досить елегантно, після чистої цілі:

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

7

Щоб видалити бін та obj перед збіркою, додайте у файл проекту:

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

Ось стаття: Як видалити папку bin та / або obj перед складанням або розгортанням


1
Однак ви хочете зробити це лише при перебудові. Якщо ви не хочете, щоб кожна збірка була відновленою!
Джош М.

4

Дуже схожий на сценарії PowerShell Стіва. Я щойно додав TestResults та пакети до нього, як це потрібно для більшості проектів.

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


3

з використання Windows PowerShell для видалення папок obj, bin та ReSharper

дуже схожа на відповідь Роберта Н з коротшим синтаксисом

  1. запустіть повноваження
  2. cd (змінити dir) до кореня папки вашого проекту
  3. вставити та запустити нижче сценарію

    dir. \ -включають bin, obj, resharper * -recurse | foreach ($ ) {rd $ _. fullname –Recurse –Force}


3

Дуже швидкий і безболісний спосіб - скористатися rimrafутилітою npm, встановити її спочатку:

> npm i rimraf -g

І тоді команда з вашого кореня проекту досить проста (яку можна зберегти у файл сценарію):

projectRoot> rimraf **/bin **/obj

Для оптимізації бажаного ефекту можна використовувати цілі подій проекту (ти можеш використовувати його BeforeRebuildі змусити його виконати попередню команду), які вказані в документах: https://docs.microsoft.com/en-us/visualstudio/ msbuild / how-to-extension-the-visual-studio-build-process? view = vs-2017

Мені подобається утиліта rimraf, оскільки вона є перехресною і дуже швидкою. Але ви також можете використовувати RemoveDirкоманду в .csproj, якщо ви вирішите перейти з цільовим параметром події. RemoveDirПідхід був добре пояснено в іншому відповіді тут @Shaman: https://stackoverflow.com/a/22306653/1534753


2

Ось відповідь, яку я дав на подібне запитання, Простий, легкий, працює досить добре і не потребує нічого іншого, ніж те, що у вас вже є у Visual Studio.

Як відповіли інші, «Clean» видалить усі артефакти, що утворюються при збірці. Але це залишить після себе все інше.

Якщо у вашому проекті MSBuild є якісь налаштування, це може спричинити проблеми і залишити після себе речі, які, на вашу думку, слід було б видалити.

Ви можете обійти цю проблему простою зміною вашого. * Proj, додавши це десь наприкінці:

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

Яке видалить усе з папки бін з поточної платформи / конфігурації.


2

Це мій пакетний файл, який я використовую для рекурсивного видалення всіх папок BIN та OBJ.

  1. Створіть порожній файл і назвіть його DeleteBinObjFolders.bat
  2. Скопіюйте і вставте наведений нижче код у DeleteBinObjFolders.bat
  3. Перемістіть файл DeleteBinObjFolders.bat у тій же папці з вашим рішенням (* .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

Чи "чисто" недостатньо добре? Зауважте, що ви можете викликати msbuild за допомогою / t: clean з командного рядка.


7
Дійсно «чисто» недостатньо добре. Особливо це стосується використання MEF. "Чисте рішення" не дозволяє позбутися видалених посилань, які можуть викликати проблеми при динамічному завантаженні DLL-файлів папки.
Олексій

5
Багато помилок "працює на моїй машині" викликані старими або несподіваними речами, які сидять навколо папок bin / obj, які не видаляються, роблячи "чисто".
Лука

1

На нашому сервері побудови ми явно видаляємо каталоги bin та obj через nant скрипти.

Кожен сценарій побудови проекту відповідає за його вихідні / тимчасові каталоги. Так добре працює. Отже, коли ми змінюємо проект і додаємо новий, ми базуємо сценарій на робочому сценарії, і ви помічаєте етап видалення і піклуєтесь про нього.

Якщо ви робите це на вашій машині розвитку логіки, я б дотримувався прибирання через Visual Studio, як згадували інші.


Іноді я просто повинен бути впевнений, що всі версії абсолютно нові. Я не можу довіряти чистому рішенню для того, щоб зробити це.deleting bin and obj часто
виявлявся

Для нас випробовуються або використовуються у виробництві лише конструкції, створені на машині побудови, тому розробники не повинні мати проблеми "чистого", і сервер збирання робить це. Також означає, що для повноцінного нарощування не потрібен жоден розробник.
Паломник Симеона

1
Який найпростіший спосіб зробити це з нантами? У мене є ієрархія декількох десятків проектів, і я краще не оскаржую сценарій видалення. =)
mpontillo

У нас створено багато виконуваних файлів / dlls-'активів', тож на кожний актив у нас є nant-скрипт, який його будує. Для кожного з них є розділ Видалити, де ми розміщуємо рядок для кожного каталогу налагодження / випуску bin / obj, який ми хочемо видалити.
Пілігрим Симеона

1

Я фактично ненавиджу obj-файли, що засмічують вихідні дерева. Я зазвичай налаштовую проекти так, щоб вони виводили obj-файли поза вихідного дерева. Для проектів C #, які я зазвичай використовую

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

Для проектів на C ++

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

1

http://vsclean.codeplex.com/

Інструмент командного рядка, який знаходить рішення Visual Studio і виконує команду Clean на них. Це дозволяє очищати / bin / * каталоги всіх тих старих проектів, які ви лежали на своєму жорсткому диску


1

Насправді ви можете взяти пропозицію щодо PS трохи далі та створити vbs-файл у каталозі проекту таким чином:

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

Для безпеки я включив параметр -WhatIf, тому видаліть його, якщо вас влаштовує список із першого запуску.


1

Я використовую незначну модифікацію Роберта Н, яка пропускає помилки та друкує файли видалення. Я Usally також очистити .vs, _resharperі packageпапки:

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

Також варто відзначити gitкоманду, яка очищує всі зміни, включаючи ігноровані файли та каталоги:

git clean -dfx

0

У нас є великий .SLN-файл із багатьма файлами проектів. Я розпочав політику створення каталогу "ViewLocal", де знаходяться всі файли, що не контролюються джерелами. Всередині цього каталогу знаходиться каталог "Інтер" та "Вихід". Для проміжних файлів і вихідних файлів відповідно.

Це, очевидно, дозволяє просто зайти в каталог "viewlocal" і зробити просте видалення, щоб позбутися від усього.

Перш ніж ви витратили час на пошуки способів вирішити цю проблему зі сценаріями, ви можете подумати над тим, щоб налаштувати щось подібне.

Я не буду брехати, але підтримка такої установки у великій організації виявилася .... цікавою. Особливо, коли ви використовуєте такі технології, як QT, які люблять обробляти файли та створювати вихідні файли без керування. Але це ціла ІНША історія!


0

Зважаючи на те, що файл PS1 присутній у currentFolder (папка, в межах якої потрібно видалити бін та obj папки)

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

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

0

Для розчину в партії. Я використовую таку команду:

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


Причина, що не використовує DIR /S /AD /B xxx
1. DIR /S /AD /B objповерне порожній список (принаймні, в моєму Windows10) 2. міститиме результат, який не очікується (папка tobj) введіть тут опис зображення
DIR /S /AD /B *objвведіть тут опис зображення


@IF EXIST %%G IF %%~aG geq dвикористовується для перевірки існуючого шляху, а шлях - це папка, а не файл.
xianyi

0

Це працює добре для мене: початок для / d / r. %% d у (bin, obj, ClientBin, Generated_Code) do @if існує "%% d" rd / s / q "%% d"


0

Для цього я використовую .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

Я думаю, ви можете клацнути правою кнопкою миші на своєму рішенні / проекті та натиснути кнопку «Очистити».

Наскільки я пам’ятаю, це працювало так. Зараз у мене немає свого VS.NET, тому я не можу перевірити його.


Це правильно, і, безумовно, найпростіші та найпростіші з усіх запропонованих рішень (якщо припустити, що це відповідає конкретній ситуації ....)
Кріс Халкроу

8
Вибачте, але це просто не так. Він не видаляє вміст / obj, який є коренем проблеми. Принаймні, така ситуація з оновленням VS 2013 3.
Огнян Димитров

Просто була така ж проблема з оновленням VS2013 4. (Примітка: VS2010 справився чудово)
juFo

Дивіться цю відповідь (на це саме те саме питання) для кращого пояснення: stackoverflow.com/a/18317221/374198
Josh M.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.