我想要删除所有的bin和obj文件夹,以便强制所有项目重新构建。

446

我参与多个项目,想要递归删除所有名称为'bin'或'obj'的文件夹,这样我就可以确定所有项目将重新构建(有时这是强制Visual Studio忘记之前所有构建的唯一方法)。

有没有快速实现这一目标的方法(例如使用.bat文件)而无需编写.NET程序?


78
如果 "生成->清理解决方案" 确实这样做,那就太好了。 - Dustin Andrews
1
我发现了一个叫做CleanBinAndObj的插件,它可以删除所有的bin和obj文件夹。对于包含多个项目的单一解决方案非常有效。 - TheLegendaryCopyCoder
30个回答

696

这取决于您想要使用的shell。

如果您正在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上的git bash或babun,以及大多数Linux / OS X shell),那么这是一种更好、更简洁的方式来实现您想要的效果:
find . -iname "bin" | xargs rm -rf
find . -iname "obj" | xargs rm -rf

而这可以通过使用“或”运算符来简化为一行代码:

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

请注意,如果您的目录或文件名包含空格或引号,find命令将直接发送这些条目,而xargs可能会将它们分成多个条目。如果您的shell支持它们,-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 }

正如下面Robert H的回答所述 - 仅需确保在选择点赞时,归功于他提供的PowerShell答案而不是我 :)

当然,最好首先在安全环境中运行您选择的任何命令以进行测试!


6
谢谢您的回答。 我遇到了一个错误:%%G 在此时是意外的。 - MichaelD
69
"%%G在这个时候是意外的" - 当您从命令行而不是批处理文件中运行它时,会发生这种情况。在这种情况下使用单个“%”符号。 - Designpattern
4
+1 你介意为我解释一下这段代码吗?麻烦了。 - fiberOptics
2
@SteveWillcock 这比清理更好。清理不会删除项目中不再引用的dll文件(残留文件)。 - Piotr Szmyd
3
如果你有 node_modules 文件夹,我建议你从中排除它。很多包都有它们自己的 bin 文件夹(比如 Gulp),如果你删除了它们,可能会导致一些问题。你可能需要运行 npm install 来重新生成 bin 文件夹。 - JED
显示剩余12条评论

484

我找到了这个帖子并获得了解决方案。继续搜索后,我找到了这个PowerShell脚本:

Get-ChildItem .\ -include bin,obj -Recurse | ForEach-Object ($_) { Remove-Item $_.FullName -Force -Recurse }
更简洁的方式:
gci -include bin,obj -recurse | remove-item -force -recurse

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


@Nigel,这个解决方案不是非常低效吗?为什么不编写一个自定义的C脚本,可以以10倍的速度运行呢? - Pacerier
8
我需要从搜索路径中排除一些文件夹,并且我喜欢使用 -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
@JohnySkovdal 同样的操作,但是更小巧: gci -exclude "*.dll" -include bin,obj -recurse | remove-item -force -recurse - Ottxr

89

这对我有用:

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

基于 superuser.com 上 这个回答


2
很棒,而且易于扩展。我使用 /d /r . %%d in (bin,obj,App_Data,packages) do @if exist "%%d" rd /s/q "%%d" - RickAndMSFT
6
@ParoX,你需要在一个 .bat 文件中运行它。 - James L

42
我写了一个powershell脚本来完成这个任务。
优点是它会打印出已删除的文件夹的摘要,以及忽略的文件夹(如果您指定了任何需要忽略的子文件夹层级)。

Output example


1
+1 非常好!刚刚发现我们实际上可以在 Window Power Shell 中像全面调试器一样调试和查看变量! - wiz_lee
我喜欢这个解决方案。我不必去搞Visual Studio,而且我可以随时运行它。非常好! - Halcyon
完全符合我的需求,但我不确定为什么这不能是一个要点而不是一个完整的存储库。 :-) - Dan Atkinson
1
干得好!我会省略所有目录扫描,因为当你有成千上万的子目录时,这可能会非常缓慢。统计数据的代价太高了 :-)。此外,我还会在 $FoldersToRemove 变量定义中添加 $_ -notmatch 'node_modules' 条件。 - Tomino
除了Tomino建议的之外,我建议排除packages文件夹。以下是更新后的列表:$FoldersToRemove = Get-ChildItem .\ -include bin,obj -Recurse | where {$_ -notmatch 'tools' -and $ -notmatch 'build' -and $ -notmatch 'node_modules' -and $_ -notmatch 'packages'} | foreach {$_.fullname} - JeeShen Lee
2022年仍然是一个不错的解决方案! - Frank Andrusiewicz

36

我过去总是在我的解决方案中添加一个新的目标来实现这一点。

<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文件不起作用,因为您无法在其上调用自定义目标,或者您知道解决此问题的方法吗? - Piotr Owsiak
4
@PiotrOwsiak 是的,您需要在与您的 .sln 文件相同的目录中创建文件 "before.MySlnFileName.sln.targets",并在其中放置您的目标定义。 - Endrju
3
你可以在目标中添加AfterTargets="Clean"属性,这将在执行重新构建时自动调用Clean任务。 - Newtopian

16

对于我来说,没有任何方法有效。我需要删除debug和release文件夹中的所有文件。我的解决方法:

1.右键点击项目,卸载,再次右键点击编辑,滚动到底部

2.插入

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

3. 保存,重新加载项目,右键单击清理即可。


13

注意:这是一个旧的答案,可能需要为VS 2019和一些对象工件进行微调才能适应新版本。在使用此方法之前,请确保VS不需要目标和输出目录中的任何内容才能成功构建。

在清理目标后,类似下面的内容就可以以相当优雅的方式实现:

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

在VS2019中,我发现这会使IDE挂起相当长的时间,并且在重建和project.assets.json方面存在问题。 - Mattias Cibien
1
谢谢Mattias,我已经添加了一个警告。我想这取决于项目类型,也许不是完全清理某些项目的好主意。应该有一种调整方法。 - vezenkov

13

一个非常快速且无痛的方法是使用 rimraf npm 工具,先全局安装它:

> npm i rimraf -g

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

projectRoot> rimraf **/bin **/obj
为了优化所需的效果,您可以利用项目事件目标(您可以使用其中之一BeforeRebuild 并使其运行前一个命令),这些目标在文档中指定:https://learn.microsoft.com/en-us/visualstudio/msbuild/how-to-extend-the-visual-studio-build-process?view=vs-2017 我喜欢rimraf工具,因为它是跨平台的并且速度非常快。但是,如果您决定使用目标事件选项,则还可以在.csproj中使用RemoveDir命令。在此由@Shaman解释得非常清楚:https://dev59.com/qnRA5IYBdhLWcg3w_DHF#22306653

1
也适用于 Mac! - Martin Indzhov
是的,(几乎?)NodeJS/npm 在任何地方都可以工作...哈。 - Vedran Mandić
2
在我看来,如果你正在使用 Unix 类操作系统,比如 Linux、macOS,那么你实际上不需要 rimraf。rm -rf **/bin **/obj 可以实现同样的功能。然而,有一点值得提醒的是,如果你的项目存在于更深层级的子目录中,这两种解决方案都无法删除这些项目的 bin/obj 目录。因此,这个解决方案适用于大多数情况,但不是所有情况。 - shukebeta

7
在构建前删除 bin 和 obj,请在项目文件中添加以下内容:
<Target Name="BeforeBuild">
    <!-- Remove obj folder -->
    <RemoveDir Directories="$(BaseIntermediateOutputPath)" />
    <!-- Remove bin folder -->
    <RemoveDir Directories="$(BaseOutputPath)" />
</Target>

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


1
不过,你只需要在重建时这样做。除非你想让每次构建都成为重建! - Josh M.

7

这非常类似于Steve的PowerShell脚本。我只是在其中添加了TestResults和packages,因为它对大多数项目都是必需的。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接