我想删除所有bin和obj文件夹以强制所有项目重建所有内容


262

我处理多个项目,所以我想递归删除所有名称为“ bin”或“ obj”的文件夹,这样我可以确定所有项目都会重建所有内容(有时这是迫使Visual Studio忘记所有以前版本的唯一方法构建)。

是否有一种无需编写.NET程序即可完成此操作的快速方法(例如,使用.bat文件)?


25
如果Build-> Clean Solution确实做到了这一点,那就太好了。
达斯汀·安德鲁斯

Answers:


411

这取决于您喜欢使用的外壳。

如果您在Windows上使用cmd shell,则应能进行以下操作:

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类型的shell(例如Windows或大多数Linux / OS X shell上的git bash或babun),则这是一种更好,更简洁的方法来执行您想要的操作:

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

并且可以使用OR将其减少为一行:

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 }

下面的罗伯特·H(Robert H)的回答所示 -如果您选择投票,请确保您将他归功于Powershell的回答,而不是我。

当然,首先安全地运行您选择的任何命令来测试它是明智的!


5
谢谢你的回答。我收到一个错误:%% G此时是意外的。
MichaelD

嗯,这很奇怪-在我的机器上运行正常(vista 64位业务)-我也会在xp机器上尝试它。
Steve Willcock

48
“ %% G这一次是意外的”-当您从命令行而不是从批处理文件中运行它时,会发生这种情况。在这种情况下,请使用单个'%'。
Designpattern 2012年

4
+1您介意为我解释代码吗?请。
FiberOptics 2014年

2
@SteveWillcock比干净好。清除不会删除项目中不再引用的dll(剩余部分)。
Piotr Szmyd 2014年

255

我发现此线程并得到宾果游戏。进行了更多搜索之后,看到了以下Power Shell脚本:

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

考虑到在看这里时没有找到答案,我想分享一下。


@Nigel,这个解决方案不是非常糟糕吗?为什么不编写一个可以以10倍的速度运行的自定义C脚本呢?
Pacerier'1

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 / r。(bin,obj,App_Data,packages)中的%% d做@if是否存在“ %% d” rd / s / q“ %% d”
RickAndMSFT 2013年

3
@ParoX你需要运行.bat文件里面
詹姆斯·L·

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

这对于s​​ln文件不起作用,因为您无法在它们上调用自定义目标,或者您知道此方法的解决方法
Piotr Owsiak 2010年

3
@PiotrOwsiak是的,您需要在拥有.sln的目录中创建文件“ before.MySlnFileName.sln.targets”,并在其中放置目标定义
Endrju 2014年

2
您可以将AfterTargets =“ Clean”添加为Target的属性,在进行清洁时直接或间接调用Clean的Clean之后将自动调用它
Newtopian 2015年

29

我写了一个Powershell脚本来做到这一点。

这样做的好处是,它会打印出已删除文件夹的摘要,如果指定了要忽略的任何子文件夹层次结构,则会将其忽略。

输出例子


1
+1非常好!刚刚发现,我们实际上可以调试并在Window Power Shell中看到变量,就像完全获取调试器一样!
wiz -_- lee

我喜欢这个解决方案。我不必弄乱Visual Studio,可以在需要时运行它。非常好!
Halcyon

完全适合我的需求,但我不确定为什么这不是要旨,而不是成熟的回购协议。:-)
Dan Atkinson

干得好!我会忽略所有目录扫描,因为当您有数千个子目录时,这可能会非常慢。价格太高,仅用于统计:-)。我还将$_ -notmatch 'node_modules'条件添加到$FoldersToRemove变量定义中
Tomino

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

要在构建之前删除bin和obj,请添加到项目文件中:

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

这是文章:如何在构建或部署之前删除bin和/或obj文件夹


1
不过,您只想在重建时执行此操作。除非您希望每个构建都是重新构建!
Josh M.

4

与Steve的PowerShell脚本非常相似。我刚刚添加了TestResults并将其打包,因为大多数项目都需要它。

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



3

一种快速而轻松的方法是使用rimrafnpm实用程序,然后先在全局进行安装:

> npm i rimraf -g

然后,从项目根目录开始的命令非常简单(可以将其保存到脚本文件中):

projectRoot> rimraf **/bin **/obj

为了优化所需的效果,您可以利用BeforeRebuild在文档中指定的项目事件目标(您可以使用的目标事件目标,并使其运行前面的命令):https : //docs.microsoft.com/zh-cn/visualstudio/ msbuild /如何扩展可视工作室的构建过程?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>

这将删除当前平台/配置的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

“干净”还不够好吗?请注意,您可以从命令行使用/ t:clean调用msbuild。


7
确实,“干净”还不够好。使用MEF时尤其如此。“干净的解决方案”不会摆脱您删除的引用,这会在动态加载文件夹的DLL时引起问题。
亚历克斯(Alex)

5
很多“在我的机器上工作”的错误是由bin / obj文件夹中的旧文件或意外文件引起的,这些东西不能通过执行“清理”操作删除。
路加福音

1

在构建服务器上,我们通过nant脚本显式删除bin和obj目录。

每个项目构建脚本都对其输出/临时目录负责。这样很好地工作。因此,当我们更改一个项目并添加一个新项目时,我们以工作脚本为基础创建脚本,然后您注意到删除阶段并负责处理。

如果您在逻辑开发机器上执行此操作,那么我会坚持通过Visual Studio进行清理,就像其他人提到的那样。


有时我只需要确保所有构建都是全新的。我不能相信这样做的干净解决方案。事实证明,删除bin和obj更可靠
MichaelD

对于我们来说,仅对“构建机器”中的构建进行测试或在生产中使用,因此开发人员不必一定是“完全干净”类型的问题,构建服务器可以做到这一点。这也意味着不需要任何开发人员即可进行完整构建。
Simeon朝圣者

1
用nant做到这一点的最简单方法是什么?我有一个由几十个项目组成的层次结构,我宁愿不要在删除脚本上失败。=)
mpontillo 2010年

我们构建了许多可执行文件/ dll“资产”,因此每个资产都有一个构建它的nant脚本。对于每个目录,都有一个Delete部分,我们在其中要删除的每个debug / release bin / obj目录下一行。
Simeon Pilgrim

1

我实际上讨厌散落在源代码树上的obj文件。我通常会设置项目,以便它们在源代码树之外输出obj文件。对于C#项目,我通常使用

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

对于C ++项目

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


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进行了轻微的修改,跳过了错误并打印了删除文件。我usally也很清楚的.vs_resharperpackage文件夹:

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中(您需要在其中删除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 / r开始。(bin,obj,ClientBin,Generated_Code)中的%% d做@if是否存在“ %% d” rd / s / q“ %% d”


0

我用bat文件与此commad做到这一点。

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的内容。至少,这是2013更新3. VS情况
奥格尼扬·季米特洛夫

VS2013更新4遇到了同样的问题。(注意:VS2010表现不错)
2015年

看到这个答案(关于这个非常相同的问题)以获得更好的解释:stackoverflow.com/a/18317221/374198
Josh M.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.