Я хочу удалить все папки bin и obj, чтобы заставить все проекты перестраивать все

263

Я работаю с несколькими проектами и хочу рекурсивно удалить все папки с именем «bin» или «obj» таким образом, я уверен, что все проекты будут перестраивать все (иногда это единственный способ заставить Visual Studio забыть все о предыдущих строит).

Есть ли быстрый способ сделать это (например, с помощью файла .bat) без необходимости писать программу .NET?

MichaelD
источник
25
Было бы неплохо, если бы Build-> Clean Solution действительно сделали это.
Дастин Эндрюс

Ответы:

412

Это зависит от того, какую оболочку вы предпочитаете использовать.

Если вы используете оболочку 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 }

как видно из ответа Роберта Н. ниже - просто убедитесь, что вы отдаете ему должное за ответ в PowerShell, а не мне, если вы решите что-либо проголосовать :)

Конечно, было бы разумно сначала выполнить любую команду, которую вы выберете в безопасном месте, чтобы проверить ее!

Стив Уиллкок
источник
5
спасибо за ваш ответ. Я получаю ошибку: %% G был неожиданным в это время.
MichaelD
Хм, это странно - он отлично работает на моей машине (Vista 64bit Business) - я тоже попробую на xp машине.
Стив Уиллкок
48
«%% G был неожиданным в это время» - это происходит, когда вы запускаете его из командной строки, а не из пакетного файла. Используйте один '%' в этом случае.
Designpattern
4
+1 Не могли бы вы объяснить код для меня? Пожалуйста.
fiberOptics
2
@ SteveWillcock Это лучше, чем чисто. Очистка не удалит библиотеки, на которые больше нет ссылок в проекте (остатки).
Петр Шмыд
256

Я нашел эту тему и получил бинго. Немного больше поиска обнаружил этот скрипт Power Shell:

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

Я думал, что поделюсь, учитывая, что я не нашел ответа, когда я искал здесь.

Роберт Х.
источник
@ Nigel, не является ли это решение крайне неэффективным? Почему бы не написать собственный сценарий C, который может работать с 10-кратной скоростью?
Pacerier
37
Вам не нужен foreach - вы должны просто иметь возможность направить gci прямо в remove-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(немного неаккуратно здесь как одна строка , хотя :))
Johny Skovdal
@ChrisJ Подумайте о добавлении нового ответа в ваше решение.
granadaCoder
66

Это сработало для меня:

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

На основании этого ответа на superuser.com

Даниэль Ренер
источник
1
Великолепно и легко расширяется. Я использую для / д / р. %% 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, так как вы не можете вызывать настраиваемые цели для них, или вы знаете обходной путь для этого
Петр Овсияк
3
@PiotrOwsiak да, вам нужно создать файл "before.MySlnFileName.sln.targets" в том же каталоге, где у вас есть .sln, и поместить туда ваши определения целей
Endrju
2
Вы можете добавить AfterTargets = "Clean" в качестве атрибута для Target, он будет автоматически вызываться после Clean, который вызывается прямо или косвенно при перестроении
Newtopian
29

Я написал скрипт PowerShell для этого.

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

Пример вывода

doblak
источник
1
+1 очень приятно! Только что обнаружил, что мы можем на самом деле отлаживать и видеть переменные как отладчик с полной выборкой в ​​Window Power Shell!
wiz -_- Lee
Мне нравится это решение. Мне не нужно связываться с Visual Studio, и я могу запустить это, когда захочу. Очень хорошо!
Halcyon
Идеально подходит для моих нужд, но я не уверен, почему это не может быть суть, а не полномасштабное репо. :-)
Дэн Аткинсон
Хорошая работа! Я бы пропустил сканирование всех каталогов, потому что, когда у вас есть тысячи подкаталогов, это может быть довольно медленным. Слишком высокая цена только для статистики :-). Также я бы добавил $_ -notmatch 'node_modules'условие для $FoldersToRemoveопределения переменной
Томино
16

У меня ничего не получалось. Мне нужно было удалить все файлы в папках bin и obj для отладки и выпуска. Мое решение:

1. Щелкните правой кнопкой мыши по проекту, выгрузите, снова щелкните правой кнопкой мыши, отредактируйте, перейдите вниз

2.Insert

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

3. Сохраните, перезагрузите проект, щелкните правой кнопкой мыши и очистите.

Kdefthog
источник
13

Нечто подобное должно делать это довольно элегантно, после чистой цели:

<Target Name="RemoveObjAndBin" AfterTargets="Clean">
    <RemoveDir Directories="$(BaseIntermediateOutputPath)" />
    <RemoveDir Directories="$(TargetDir)" />
</Target>
vezenkov
источник
7

Чтобы удалить bin и 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 }
Aboo
источник
3

с помощью Windows PowerShell для удаления OBJ, BIN и ReSharper папки

очень похоже на ответ Роберта Х с более коротким синтаксисом

  1. запустить PowerShell
  2. cd (изменить каталог) в корень вашей папки проекта
  3. вставьте и запустите приведенный ниже скрипт

    dir. \ -include bin, obj, resharper * -recurse | foreach ($ ) {rd $ _. полное имя –Recurse –Force}

Иман
источник
3

Очень быстрый и безболезненный способ - использовать rimrafутилиту npm, сначала установить ее глобально:

> npm i rimraf -g

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

projectRoot> rimraf **/bin **/obj

Чтобы оптимизировать желаемый эффект, вы можете использовать цели проекта (которые вы могли бы использовать BeforeRebuildи запустить предыдущую команду), которые указаны в документации: https://docs.microsoft.com/en-us/visualstudio/ MSBuild / как к простираться-на-зрительно-студия-сборки-процесс? вид = VS-2017

Мне нравится утилита rimraf, так как она кроссплатформенная и очень быстрая. Но вы также можете использовать RemoveDirкоманду в .csproj, если решите использовать опцию target event. RemoveDirПодход был хорошо объяснено в другом ответе здесь @Shaman: https://stackoverflow.com/a/22306653/1534753

Ведран Мандич
источник
2

Вот ответ, который я дал на аналогичный вопрос: Простой, легкий, работает довольно хорошо и не требует ничего, кроме того, что у вас уже есть в Visual Studio.

Как уже отвечали другие, Clean удалит все артефакты, сгенерированные сборкой. Но это оставит позади все остальное.

Если у вас есть какие-то настройки в вашем проекте MSBuild, это может привести к проблемам и оставить вещи, которые вы могли бы удалить.

Вы можете обойти эту проблему, просто изменив свой. * Proj, добавив его где-то ближе к концу:

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

Который удалит все в вашей папке bin текущей платформы / конфигурации.

Newtopian
источник
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, как уже упоминали другие.

Симеон Пилигрим
источник
иногда я просто должен быть уверен, что все сборки абсолютно новые. Я не могу доверять чистому решению для этого. Удаление bin и obj часто оказывалось более надежным
MichaelD
Для нас только сборки с «машины сборки» тестируются или используются в производстве, поэтому у разработчиков не должно быть проблем со «чистым» типом, и сервер сборки делает это. Также означает, что для полной сборки не нужен ни один разработчик.
Симеон Пилигрим
1
Какой самый простой способ сделать это с Nant? У меня есть иерархия из пары десятков проектов, и я бы предпочел не пропускать работу сценария удаления. =)
mpontillo
У нас есть много встроенных исполняемых файлов / библиотек 'dll', поэтому для каждого ресурса у нас есть скрипт nant, который его создает. Для каждого из них есть раздел Delete, в котором мы помещаем строку для каждого каталога debug / release 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, поэтому удалите его, если вы удовлетворены списком при первом запуске.

KL XL
источник
1

Я использую небольшую модификацию Robert H, которая пропускает ошибки и печатает удаленные файлы. Я обычно также очищаю .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
eugstman
источник
0

У нас есть большие файлы .SLN со многими файлами проекта. Я начал политику наличия директории «ViewLocal», в которой находятся все неконтролируемые файлы. Внутри этого каталога находится каталог Inter и Out. Для промежуточных файлов и выходных файлов соответственно.

Это, очевидно, позволяет легко перейти в каталог 'viewlocal' и выполнить простое удаление, чтобы избавиться от всего.

Прежде чем вы потратите время на поиск способа обойти это с помощью скриптов, вы можете подумать о создании чего-то подобного.

Хотя я не буду лгать, поддержание такой настройки в большой организации оказалось… интересным. Особенно, когда вы используете такие технологии, как QT, которые любят обрабатывать файлы и создавать неконтролируемые исходные файлы. Но это целая другая история!

pj4533
источник
0

Учитывая, что файл PS1 присутствует в currentFolder (папка, в которой вам нужно удалить папки bin и obj)

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

Get-ChildItem $currentFolder -include bin,obj -Recurse | foreach ($_) { remove-item $_.fullname -Force -Recurse }
ShivanandSK
источник
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введите описание изображения здесь

xianyi
источник
@IF EXIST %%G IF %%~aG geq dиспользуется для проверки существующего пути, а путь - это папка, а не файл.
Сяньи
0

Это прекрасно работает для меня: начать для / д / р. %% d в (bin, obj, ClientBin, Generated_Code) действительно ли @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"
Hacko
источник
-1

Я думаю, что вы можете щелкнуть правой кнопкой мыши ваше решение / проект и нажать кнопку «Очистить».

Насколько я помню, это работало так. У меня нет с собой VS.NET, поэтому я не могу его проверить.

др. злой
источник
Это правильно, и, безусловно, самое простое и простое из всех предложенных решений (при условии, что оно соответствует конкретной ситуации ....)
Крис Хэлкроу
8
Извините, но это просто неправда. Он не удаляет содержимое / obj, которое является причиной проблемы. По крайней мере, так обстоят дела с обновлением 3 VS 2013.
Огнян Димитров
Просто была такая же проблема с VS2013 обновления 4. (Примечание: VS2010 делает штраф)
ЮФО
См. Этот ответ (по этому же вопросу) для лучшего объяснения: stackoverflow.com/a/18317221/374198
Джош М.