Quiero eliminar todas las carpetas bin y obj para forzar a todos los proyectos a reconstruir todo

263

Trabajo con varios proyectos y quiero eliminar de forma recursiva todas las carpetas con el nombre 'bin' u 'obj' de esa manera, estoy seguro de que todos los proyectos reconstruirán todo (a veces es la única forma de obligar a Visual Studio a olvidar todo lo anterior construcciones).

¿Hay una manera rápida de lograr esto (con un archivo .bat por ejemplo) sin tener que escribir un programa .NET?

MichaelD
fuente
25
Sería bueno si Build-> Clean Solution realmente hiciera esto.
Dustin Andrews

Respuestas:

412

Esto depende del shell que prefiera usar.

Si está utilizando el shell cmd en Windows, lo siguiente debería 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"

Si está utilizando un shell de tipo bash o zsh (como git bash o babun en Windows o la mayoría de los shells Linux / OS X), esta es una forma mucho más agradable y sucinta de hacer lo que desea:

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

y esto se puede reducir a una línea con un OR:

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

Tenga en cuenta que si sus directorios de nombres de archivo contienen espacios o comillas, find enviará esas entradas tal cual, que xargs pueden dividir en múltiples entradas. Si su shell los admite -print0y -0evitará esta deficiencia, los ejemplos anteriores se convertirán en:

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

y:

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

Si está utilizando Powershell, puede usar esto:

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

como se ve en la respuesta de Robert H a continuación , solo asegúrate de darle crédito por la respuesta de PowerShell en lugar de mí si eliges votar algo :)

¡Por supuesto, sería prudente ejecutar cualquier comando que elija en un lugar seguro primero para probarlo!

Steve Willcock
fuente
55
Gracias por tu respuesta. Recibo un error: %% G fue inesperado en este momento.
MichaelD
Hmm, eso es extraño: funciona bien en mi máquina (vista negocio de 64 bits). También lo intentaré en una máquina xp.
Steve Willcock
48
"%% G fue inesperado en este momento": esto sucede cuando lo ejecuta desde la línea de comandos en lugar de hacerlo dentro de un archivo por lotes. Use '%' s individuales en este caso.
Designpattern
44
+1 ¿Te importaría explicarme el código? Por favor.
fiberOptics
2
@SteveWillcock Es mejor que limpiar. Clean ya no eliminará los archivos dlls que ya no se mencionan en el proyecto (restos).
Piotr Szmyd
256

Encontré este hilo y obtuve bingo. Un poco más de búsqueda apareció en este script de Power Shell:

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

Pensé en compartir, considerando que no encontré la respuesta cuando estaba buscando aquí.

Robert H.
fuente
@Nigel, ¿no es esta solución extremadamente improductiva? ¿Por qué no escribir un script C personalizado que pueda ejecutarse a 10 veces la velocidad?
Pacerier
37
No necesita el foreach: solo debe poder canalizar gci directamente en remove-item (es decir, gci -include bin,obj -recurse | remove-item -force -recurse)
Chris J
1
También necesitaba excluir carpetas de la ruta de búsqueda, y me gusta que la -WhatIfbandera se pruebe primero, así que terminé con esto: $foldersToRemove='bin','obj';[string[]]$foldersToIgnore='ThirdParty';Get-ChildItem .\ -Include $foldersToRemove -Recurse|Where-Object{$_.FullName -inotmatch "\\$($foldersToIgnore -join '|')\\"}|Remove-Item -Force -Recurse -WhatIf(aunque un poco desordenado aquí como una línea :))
Johny Skovdal
@ChrisJ Considere agregar una nueva respuesta con su solución.
granadaCoder
66

Esto funcionó para mí:

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

Basado en esta respuesta en superuser.com

Daniel Rehner
fuente
1
Genial y fácil de extender. Yo uso para / d / r. %% d en (bin, obj, App_Data, paquetes) si @ existe "%% d" rd / s / q "%% d"
RickAndMSFT
3
@ParoX necesitas ejecutarlo dentro de un archivo .bat
James L
33

Solía ​​agregar siempre un nuevo objetivo en mis soluciones para lograr esto.

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

Y puedes llamarlo desde la línea de comando

msbuild /t:clean_folders

Este puede ser su archivo por lotes.

msbuild /t:clean_folders
PAUSE
Jhonny D. Cano -Leftware-
fuente
Esto no funciona para un archivo sln ya que no puede llamar a objetivos personalizados en ellos o conoce una solución para esto
Piotr Owsiak
3
@PiotrOwsiak sí, debe crear el archivo "before.MySlnFileName.sln.targets" en el mismo directorio donde tiene su .sln y colocar sus definiciones de destino
Endrju
2
puede agregar AfterTargets = "Clean" como un atributo al Target, se llamará automáticamente después de Clean, que se invoca directa o indirectamente al hacer una reconstrucción
Newtopian
29

Escribí un script de PowerShell para hacerlo.

La ventaja es que imprime un resumen de las carpetas eliminadas e ignoradas si especificó que se debe ignorar cualquier jerarquía de subcarpetas.

Ejemplo de salida

doblak
fuente
1
+1 muy lindo! ¡Acabo de descubrir que podemos depurar y ver las variables como un depurador completo en Window Power Shell!
wiz -_- lee
Me gusta esta solución No tengo que meterme con Visual Studio y puedo ejecutar esto cuando quiera. ¡Muy agradable!
Halcyon
Se adapta perfectamente a mis necesidades, pero no estoy seguro de por qué esto no podría ser una esencia en lugar de un repositorio completo. :-)
Dan Atkinson
¡Buen trabajo! Omitiría la exploración de todos los directorios porque cuando tiene miles de subdirectorios, esto podría ser bastante lento. Precio demasiado alto solo para estadísticas :-). También agregaría $_ -notmatch 'node_modules'condición a la $FoldersToRemovedefinición variable
Tomino
16

Nada me funcionó. Necesitaba eliminar todos los archivos en las carpetas bin y obj para depurar y liberar. Mi solución:

1.Haga clic derecho en el proyecto, descargue, haga clic con el botón derecho nuevamente edite, vaya al final

2.Insertar

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

3. Guarde, vuelva a cargar el proyecto, haga clic derecho en limpiar y listo.

Kdefthog
fuente
13

Algo así debería hacerlo de una manera bastante elegante, después de un objetivo limpio:

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

Para eliminar bin y obj antes de compilar, agregue al archivo del proyecto:

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

Aquí está el artículo: Cómo eliminar la carpeta bin y / u obj antes de la compilación o implementación

Chamán
fuente
1
Sin embargo, solo querrás hacer esto en una reconstrucción. ¡A menos que quieras que cada construcción sea una reconstrucción!
Josh M.
4

Muy similar a los scripts de Steve PowerShell. Acabo de agregar TestResults y paquetes, ya que es necesario para la mayoría de los proyectos.

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

Una forma muy rápida e indolora es utilizar la rimrafutilidad npm, instalarla globalmente primero:

> npm i rimraf -g

Y luego el comando desde la raíz del proyecto es bastante simple (que se puede guardar en un archivo de script):

projectRoot> rimraf **/bin **/obj

Para optimizar el efecto deseado, puede aprovechar los objetivos del evento del proyecto (el que podría usar es BeforeRebuildy hacer que ejecute el comando anterior) que se especifican en los documentos: https://docs.microsoft.com/en-us/visualstudio/ msbuild / how-to-extend-the-visual-studio-build-process? view = vs-2017

Me gusta la utilidad rimraf, ya que es crossplat y realmente rápida. Pero también puede usar el RemoveDircomando en el .csproj si decide ir con la opción de evento de destino. El RemoveDirenfoque fue bien explicado en otra respuesta aquí por @Shaman: https://stackoverflow.com/a/22306653/1534753

Vedran Mandić
fuente
2

Aquí está la respuesta que le di a una pregunta similar, simple, fácil, funciona bastante bien y no requiere nada más que lo que ya tiene con Visual Studio.

Como otros ya han respondido, Clean eliminará todos los artefactos generados por la compilación. Pero dejará atrás todo lo demás.

Si tiene algunas personalizaciones en su proyecto de MSBuild, esto podría significar problemas y dejar cosas que cree que deberían haberse eliminado.

Puede evitar este problema con un simple cambio en su. * Proj agregando esto en algún lugar cerca del final:

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

Lo que eliminará todo en su carpeta bin de la plataforma / configuración actual.

Newtopian
fuente
2

Este es mi archivo por lotes que utilizo para eliminar todas las carpetas BIN y OBJ de forma recursiva.

  1. Cree un archivo vacío y asígnele el nombre DeleteBinObjFolders.bat
  2. Copie y pegue el código del código siguiente en DeleteBinObjFolders.bat
  3. Mueva el archivo DeleteBinObjFolders.bat en la misma carpeta con su archivo de solución (* .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
Alper Ebicoglu
fuente
1

¿'Limpio' no es lo suficientemente bueno? Tenga en cuenta que puede llamar a msbuild con / t: clean desde la línea de comandos.

Brian
fuente
77
De hecho, "limpio" no es lo suficientemente bueno. Esto es especialmente cierto cuando se usa MEF. "Solución limpia" no elimina las referencias que ha eliminado, lo que puede causar problemas al cargar dinámicamente los archivos DLL de una carpeta.
Alex
55
Muchos errores de "funciona en mi máquina" son causados ​​por cosas viejas o inesperadas que se encuentran en las carpetas bin / obj que no se eliminan haciendo una "limpieza".
Lucas
1

En nuestro servidor de compilación, eliminamos explícitamente los directorios bin y obj, a través de scripts nant.

Cada script de compilación del proyecto es responsable de sus directorios de salida / temp. Funciona muy bien de esa manera. Entonces, cuando cambiamos un proyecto y agregamos uno nuevo, basamos el guión en un guión de trabajo, y usted nota la etapa de eliminación y se encarga de ello.

Si lo hace en su máquina de desarrollo lógico, me quedaría con la limpieza a través de Visual Studio como otros han mencionado.

Peregrino Simeón
fuente
a veces solo debo asegurarme de que todas las compilaciones sean completamente nuevas. No puedo confiar en una solución limpia para hacer eso. Eliminar bin y obj a menudo ha demostrado ser más confiable
MichaelD
Para nosotros, solo las compilaciones de la 'máquina de compilación' se prueban o se usan en producción, por lo que los desarrolladores no deben tener problemas de tipo 'todo limpio', y el servidor de compilación lo hace. También significa que no se necesita un desarrollador para realizar una compilación completa.
Simeon Pilgrim
1
¿Cuál es la forma más fácil de hacer esto con nant? Tengo una jerarquía de un par de docenas de proyectos y prefiero no fallar en un script de eliminación. =)
mpontillo
Tenemos muchos ejecutables / dlls 'activo' construido, así que por activo tenemos un script nant que lo construye. Para cada uno hay una sección Eliminar donde colocamos una línea para cada directorio de depuración / liberación bin / obj que queremos eliminar.
Simeon Pilgrim
1

De hecho, odio los archivos obj que ensucian los árboles de origen. Por lo general, configuro proyectos para que generen archivos obj fuera del árbol de origen. Para proyectos de C # usualmente uso

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

Para proyectos en C ++

 IntermediateDirectory="..\..\obj\$(ProjectName)\$(ConfigurationName)"
Juozas Kontvainis
fuente
1

http://vsclean.codeplex.com/

Herramienta de línea de comando que encuentra soluciones de Visual Studio y ejecuta el comando Limpiar en ellas. Esto le permite limpiar los directorios / bin / * de todos esos proyectos antiguos que tiene en su disco duro

Joel Martinez
fuente
1

En realidad, podría llevar la sugerencia de PS un poco más lejos y crear un archivo vbs en el directorio del proyecto como este:

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 seguridad, he incluido el parámetro -WhatIf, así que elimínelo si está satisfecho con la lista en la primera ejecución.

KL XL
fuente
1

Utilizo una ligera modificación de Robert H que omite errores e imprime los archivos eliminados. Usualmente también borro las carpetas .vs, _resharpery package:

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

También vale la pena señalar es el gitcomando que borra todos los cambios, incluidos los archivos y directorios ignorados:

git clean -dfx
eugstman
fuente
0

Tenemos un gran archivo .SLN con muchos archivos de proyecto. Comencé la política de tener un directorio "ViewLocal" donde se encuentran todos los archivos no controlados por la fuente. Dentro de ese directorio hay un directorio 'Inter' y 'Out'. Para los archivos intermedios y los archivos de salida, respectivamente.

Obviamente, esto hace que sea fácil ir a su directorio 'viewlocal' y hacer una simple eliminación, para deshacerse de todo.

Antes de dedicar tiempo a encontrar una manera de solucionar esto con scripts, puede pensar en configurar algo similar.

Sin embargo, no mentiré, mantener esa configuración en una gran organización ha resultado ... interesante. Especialmente cuando utiliza tecnologías como QT que les gusta procesar archivos y crear archivos fuente no controlados por fuente. ¡Pero esa es toda una OTRA historia!

pj4533
fuente
0

Teniendo en cuenta que el archivo PS1 está presente en la carpeta actual (la carpeta dentro de la cual necesita eliminar las carpetas bin y obj)

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

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

Para la solución en lote. Estoy usando el siguiente comando:

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


La razón por la que no se usa DIR /S /AD /B xxx
1. DIR /S /AD /B objdevolverá una lista vacía (al menos en mi Windows10) 2. contendrá el resultado que no se espera (carpeta tobj) ingrese la descripción de la imagen aquí
DIR /S /AD /B *objingrese la descripción de la imagen aquí

xianyi
fuente
@IF EXIST %%G IF %%~aG geq dse utiliza para verificar la ruta existente y la ruta es una carpeta, no un archivo.
xianyi
0

Esto funciona bien para mí: comience por / d / r. %% d en (bin, obj, ClientBin, Generated_Code) si @ existe "%% d" rd / s / q "%% d"

Mudit Sharma
fuente
0

Utilizo el archivo .bat con este comando para hacer eso.

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
fuente
-1

Creo que puede hacer clic derecho en su solución / proyecto y hacer clic en el botón "Limpiar".

Por lo que recuerdo, estaba funcionando así. No tengo mi VS.NET ahora, así que no puedo probarlo.

Dr. mal
fuente
Eso es correcto, y con mucho, la solución más simple y fácil de todas las sugeridas (suponiendo que sea apropiada para la situación específica ...)
Chris Halcrow
8
Lo siento, pero esto simplemente no es cierto. No elimina los contenidos de / obj que son la raíz del problema. Al menos esta es la situación con VS 2013 actualización 3.
Ognyan Dimitrov
Acabo de tener el mismo problema con VS2013 actualización 4. (Nota: VS2010 estaba funcionando bien)
juFo
Vea esta respuesta (sobre esta misma pregunta) para una mejor explicación: stackoverflow.com/a/18317221/374198
Josh M.