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


263

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

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


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 для этого.

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

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


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. Сохраните, перезагрузите проект, щелкните правой кнопкой мыши и очистите.


13

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

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

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 }


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 текущей платформы / конфигурации.


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, поэтому удалите его, если вы удовлетворены списком при первом запуске.


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

0

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

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

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

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


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 }

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используется для проверки существующего пути, а путь - это папка, а не файл.
Сяньи

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"

-1

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

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


Это правильно, и, безусловно, самое простое и простое из всех предложенных решений (при условии, что оно соответствует конкретной ситуации ....)
Крис Хэлкроу

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

Просто была такая же проблема с VS2013 обновления 4. (Примечание: VS2010 делает штраф)
ЮФО

См. Этот ответ (по этому же вопросу) для лучшего объяснения: stackoverflow.com/a/18317221/374198
Джош М.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.