Quero excluir todas as pastas bin e obj para forçar todos os projetos a reconstruir tudo


263

Trabalho com vários projetos e quero excluir recursivamente todas as pastas com o nome 'bin' ou 'obj' dessa maneira. Tenho certeza de que todos os projetos reconstruirão tudo (às vezes, é a única maneira de forçar o Visual Studio a esquecer tudo sobre o anterior. cria).

Existe uma maneira rápida de fazer isso (com um arquivo .bat por exemplo) sem precisar escrever um programa .NET?


25
Seria bom se o Build-> Clean Solution realmente fizesse isso.
Dustin Andrews

Respostas:


412

Isso depende do shell que você preferir usar.

Se você estiver usando o cmd shell no Windows, o seguinte deverá funcionar:

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"

Se você estiver usando um shell do tipo bash ou zsh (como git bash ou babun no Windows ou na maioria dos shells Linux / OS X), esta é uma maneira muito mais agradável e sucinta de fazer o que você deseja:

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

e isso pode ser reduzido a uma linha com um OR:

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

Observe que, se seus diretórios de nomes de arquivos contiverem espaços ou aspas, o find enviará essas entradas como estão, que xargs podem dividir em várias entradas. Se o seu shell os suportar, -print0e -0contornar essa falha, os exemplos acima se tornarão:

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

e:

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

Se você estiver usando o Powershell, poderá usar o seguinte:

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

como visto na resposta de Robert H abaixo - apenas certifique-se de dar crédito a ele pela resposta do PowerShell, e não por mim, se você escolher votar novamente qualquer coisa :)

É claro que seria sensato executar qualquer comando que você escolher em algum lugar seguro primeiro para testá-lo!


5
thx pela sua resposta. Eu recebo um erro: %% G foi inesperado no momento.
22430 MichaelD

Hmm, isso é estranho - funciona bem na minha máquina (negócios com vista de 64 bits) - também vou tentar em uma máquina xp.
21340 Steve Stevecock

48
"%% G foi inesperado no momento" - isso acontece quando você o executa na linha de comando e em um arquivo em lotes. Use '%' s simples neste caso.
Designpattern

4
+1 Você se importaria de explicar o código para mim? Por favor.
fibras ópticas

2
@SteveWillcock É melhor que limpo. O Clean não removerá as DLLs que não são mais referenciadas no projeto (sobras).
Piotr Szmyd

256

Encontrei este tópico e peguei bingo. Um pouco mais de pesquisa mostrou esse script do shell de energia:

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

Pensei em compartilhar, considerando que não encontrei a resposta quando estava procurando aqui.


@ Nigel, esta solução não é extremamente insatisfatória? Por que não escrever um script C personalizado que possa rodar em 10x a velocidade?
Pacerier

37
Você não precisa o foreach - você deve apenas ser capaz de GCI tubo direto para remove-item (ou seja, gci -include bin,obj -recurse | remove-item -force -recurse)
Chris J

1
Eu precisava também excluir pastas do SearchPath, e eu como a -WhatIfbandeira para primeiro teste, então eu acabei com isso: $foldersToRemove='bin','obj';[string[]]$foldersToIgnore='ThirdParty';Get-ChildItem .\ -Include $foldersToRemove -Recurse|Where-Object{$_.FullName -inotmatch "\\$($foldersToIgnore -join '|')\\"}|Remove-Item -Force -Recurse -WhatIf(um pouco confuso aqui como uma linha embora :))
Johny Skovdal

@ChrisJ Considere adicionar uma nova resposta com sua solução.
granadaCoder

66

Isso funcionou para mim:

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

Com base nesta resposta em superuser.com


1
Ótimo e fácil de estender. Eu uso para / d / r. %% d em (bin, obj, App_Data, pacotes) fazer @if existe "%% d" rd / s / q "%% d"
RickAndMSFT

3
@ParoX você precisa executá-lo dentro de um arquivo .bat
James L

33

Costumo adicionar sempre um novo alvo em minhas soluções para conseguir isso.

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

E você pode chamá-lo na linha de comando

msbuild /t:clean_folders

Este pode ser o seu arquivo em lotes.

msbuild /t:clean_folders
PAUSE

Isso não funciona para um arquivo SLN desde que você não pode chamar alvos personalizados sobre eles ou você sabe uma solução para este
Piotr Owsiak

3
@PiotrOwsiak sim, você precisa criar o arquivo "before.MySlnFileName.sln.targets" no mesmo diretório onde você tem o seu .sln e colocar lá as suas definições de alvo
Endrju

2
você pode adicionar AfterTargets = "Clean" como um atributo ao Target, ele será automaticamente chamado após o Clean, que é invocado direta ou indiretamente ao fazer uma reconstrução.
Newtopian

29

Eu escrevi um script do PowerShell para fazer isso.

A vantagem é que ela imprime um resumo das pastas excluídas e as ignoradas, se você especificou qualquer hierarquia de subpastas a ser ignorada.

Exemplo de saída


1
+1 muito bom! Acabei de descobrir que podemos realmente depurar e ver as variáveis ​​como um depurador de busca completa no Window Power Shell!
precisa saber é o seguinte

Eu gosto desta solução. Não preciso mexer no Visual Studio e posso executar isso quando quiser. Muito agradável!
Halcyon

Adapta-se perfeitamente às minhas necessidades, mas não sei por que isso não poderia ser uma essência, e não um repo completo. :-)
Dan Atkinson

Bom trabalho! Eu omitiria a verificação de todos os diretórios porque, quando você tem milhares de subdiretórios, isso pode ser bastante lento. Preço muito alto apenas para estatísticas :-). Também eu gostaria de acrescentar $_ -notmatch 'node_modules'condições para $FoldersToRemovedefinição de variável
Tomino

16

Nada funcionou para mim. Eu precisava excluir todos os arquivos nas pastas bin e obj para depuração e lançamento. Minha solução:

1.Clique com o botão direito do mouse no projeto, descarregue, clique com o botão direito novamente em editar, vá para o final

2.Inserir

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

3. Salve, recarregue o projeto, clique com o botão direito do mouse em limpo e pronto.


13

Algo assim deve fazê-lo de uma maneira bastante elegante, após um objetivo limpo:

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

7

Para excluir bin e obj antes da compilação, adicione ao arquivo do projeto:

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

Aqui está o artigo: Como remover a pasta bin e / ou obj antes da compilação ou implantação


1
Você só desejará fazer isso em uma reconstrução. A menos que você queira que cada build seja reconstruído!
Josh M.

4

Muito semelhante aos scripts do Steve PowerShell. Acabei de adicionar TestResults e pacotes a ele, pois é necessário para a maioria dos projetos.

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



3

Uma maneira muito rápida e simples é usar o rimrafutilitário npm, instalá-lo globalmente primeiro:

> npm i rimraf -g

E então o comando da raiz do projeto é bastante simples (que pode ser salvo em um arquivo de script):

projectRoot> rimraf **/bin **/obj

Para otimizar o efeito desejado, você pode alavancar os destinos de eventos do projeto (aquele que você pode usar BeforeRebuilde executar o comando anterior) especificados nos documentos: https://docs.microsoft.com/en-us/visualstudio/ msbuild / como estender o processo de criação do estúdio visual? view = vs-2017

Eu gosto do utilitário rimraf, pois é multiplataforma e muito rápido. Mas também é possível usar o RemoveDircomando no .csproj se você decidir ir com a opção de evento de destino. A RemoveDirabordagem foi bem explicada em outra resposta aqui por @ Shaman: https://stackoverflow.com/a/22306653/1534753


2

Aqui está a resposta eu dei a uma pergunta semelhante: Simples, fácil, funciona muito bem e não requer nada além do que você já tem com o Visual Studio.

Como outros já responderam, o Clean removerá todos os artefatos gerados pela construção. Mas isso deixará para trás todo o resto.

Se você tiver algumas personalizações no seu projeto MSBuild, isso pode significar problemas e deixar para trás coisas que você acha que deveria ter excluído.

Você pode contornar esse problema com uma simples alteração no seu. * Proj adicionando-o em algum lugar próximo ao final:

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

O que removerá tudo da sua pasta bin da plataforma / configuração atual.


2

Este é o meu arquivo em lotes que eu uso para excluir todas as pastas BIN e OBJ recursivamente.

  1. Crie um arquivo vazio e denomine -o DeleteBinObjFolders.bat
  2. Copie e cole o código abaixo no código DeleteBinObjFolders.bat
  3. Mova o arquivo DeleteBinObjFolders.bat na mesma pasta com o arquivo de solução (* .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

'Limpo' não é bom o suficiente? Observe que você pode chamar o msbuild com / t: clean na linha de comando.


7
De fato, "limpo" não é bom o suficiente. Isto é especialmente verdade ao usar o MEF. "Solução Limpa" não elimina as referências removidas, o que pode causar problemas ao carregar dinamicamente as DLLs de uma pasta.
18712 Alex

5
Muitos bugs do "works on my machine" são causados ​​por coisas antigas ou inesperadas nas pastas bin / obj que não são removidas ao fazer uma "limpeza".
Luke

1

Em nosso servidor de compilação, excluímos explicitamente os diretórios bin e obj, por meio de scripts nant.

Cada script de construção do projeto é responsável por seus diretórios de saída / temp. Funciona bem dessa maneira. Portanto, quando alteramos um projeto e adicionamos um novo, baseamos o script em um script de trabalho, e você percebe o estágio de exclusão e cuida dele.

Se você fizer isso em sua máquina de desenvolvimento lógico, eu ficaria limpo através do Visual Studio, como outros já mencionaram.


Às vezes eu só tenho que ter certeza de que todas as compilações são completamente novas. Não posso confiar em solução limpa para fazer bin that.deleting e obj muitas vezes provou mais confiável
MichaelD

Para nós, apenas compilações da 'máquina de compilação' são testadas ou usadas na produção, portanto, os desenvolvedores não precisam ter problemas do tipo 'todos limpos', e o servidor de compilação faz isso. Também significa que nenhum desenvolvedor é necessário para fazer uma compilação completa.
Simeon Pilgrim

1
Qual é a maneira mais fácil de fazer isso com o nant? Eu tenho uma hierarquia de algumas dúzias de projetos e prefiro não ignorar um script de exclusão. =)
mpontillo

Temos muitos 'ativos' executáveis ​​/ dlls construídos, portanto, por ativo, temos um script nant que o constrói. Para cada um, há uma seção Excluir, onde colocamos uma linha para cada diretório debug / release bin / obj que queremos excluir.
Simeon Pilgrim

1

Na verdade, eu odeio arquivos obj espalhando as árvores de origem. Eu costumo configurar projetos para que eles produzam arquivos obj fora da árvore de origem. Para projetos em C # eu costumo usar

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

Para projetos C ++

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

1

http://vsclean.codeplex.com/

Ferramenta de linha de comando que localiza soluções do Visual Studio e executa o comando Limpar nelas. Isso permite que você limpe os diretórios / bin / * de todos os projetos antigos existentes no disco rígido


1

Você pode levar a sugestão do PS um pouco mais longe e criar um arquivo vbs no diretório do projeto, assim:

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

Por segurança, incluí o parâmetro -WhatIf; remova-o se estiver satisfeito com a lista na primeira execução.


1

Eu uso uma ligeira modificação de Robert H, que pula erros e imprime os arquivos de exclusão. I usally também limpar as .vs, _resharpere packagepastas:

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

Também vale a pena notar o gitcomando que limpa todas as alterações, inclusive arquivos e diretórios ignorados:

git clean -dfx

0

Temos um grande arquivo .SLN com muitos arquivos de projeto. Comecei a política de ter um diretório "ViewLocal" onde estão localizados todos os arquivos não controlados por código fonte. Dentro desse diretório, há um diretório 'Inter' e um 'Out'. Para os arquivos intermediários e os arquivos de saída, respectivamente.

Obviamente, isso facilita o acesso ao diretório 'viewlocal' e a exclusão simples de tudo.

Antes de dedicar algum tempo a descobrir uma maneira de solucionar isso com scripts, você pode pensar em configurar algo semelhante.

Não vou mentir, porém, manter essa configuração em uma grande organização provou ser ... interessante. Especialmente quando você usa tecnologias como QT que gostam de processar arquivos e criar arquivos de origem não controlados por fontes. Mas isso é outra história!


0

Considerando que o arquivo PS1 está presente na currentFolder (a pasta na qual você precisa excluir as pastas bin e obj)

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

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

0

Para a solução em lote. Estou usando o seguinte comando:

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


O motivo de não usar DIR /S /AD /B xxx
1. DIR /S /AD /B objretornará uma lista vazia (pelo menos no meu Windows 10) 2. conterá o resultado que não é esperado (pasta tobj) insira a descrição da imagem aqui
DIR /S /AD /B *objinsira a descrição da imagem aqui


@IF EXIST %%G IF %%~aG geq dé usado para verificar o caminho existente e o caminho é uma pasta, não um arquivo.
xianyi 7/01/19

0

Isso funciona bem para mim: inicie para / d / r. %% d (bin, obj, ClientBin, Generated_Code) existe @se existir "%% d" rd / s / q "%% d"


0

Eu uso o arquivo .bat com essa vírgula para fazer isso.

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

Eu acho que você pode clicar com o botão direito do mouse na sua solução / projeto e clicar no botão "Limpar".

Tanto quanto me lembro, estava funcionando assim. Eu não tenho meu VS.NET comigo agora, então não posso testá-lo.


Isso é correto, e de longe o mais simples e mais fácil de todas as soluções sugeridas (assumindo que é apropriado para a situação específica ....)
Chris Halcrow

8
Desculpe, mas isso simplesmente não é verdade. Ele não exclui o conteúdo de / obj, que é a raiz do problema. Pelo menos, esta é a situação com a atualização 3. do VS 2013.
Ognyan Dimitrov

Só tinha o mesmo problema com VS2013 atualização 4. (Nota: VS2010 estava indo bem)
jufo

Veja esta resposta (sobre esta mesma questão) para uma explicação melhor: stackoverflow.com/a/18317221/374198
Josh M.
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.