ChatGPT解决这个技术问题 Extra ChatGPT

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

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

有没有一种快速的方法来完成这个(例如使用 .bat 文件)而无需编写 .NET 程序?

如果 Build->Clean Solution 确实做到了,那就太好了。

B
Brondahl

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

如果您在 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 可能会拆分为多个条目。如果您的 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's answer below 中所示 - 如果您选择对任何内容进行投票,请确保您将 powershell 答案归功于他而不是我 :)

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


谢谢你的回答。我收到一个错误:此时 %%G 出乎意料。
“此时 %%G 出乎意料” - 当您从命令行而不是从批处理文件中运行它时会发生这种情况。在这种情况下使用单个 '%'。
+1您介意为我解释一下代码吗?请。
@SteveWillcock 这比干净好。 Clean 不会删除项目中不再引用的 dll(剩余部分)。
如果你有它,我会建议排除 node_modules 。许多软件包都有自己的 bin 文件夹(如 Gulp),如果您删除它们,可能会导致事情中断。您可能必须运行 npm install 来重新填充 bin 文件夹。
M
Morse

我找到了这个线程并得到了宾果游戏。多一点搜索发现了这个强大的 shell 脚本:

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

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


@Nigel,这个解决方案不是性能极差吗?为什么不编写一个可以以 10 倍速度运行的自定义 C 脚本呢?
您不需要 foreach - 您应该能够将 gci 直接通过管道传输到 remove-item(即 gci -include bin,obj -recurse | remove-item -force -recurse
我还需要从搜索路径中排除文件夹,并且我喜欢首先测试 -WhatIf 标志,所以我最终得到了这个:$foldersToRemove='bin','obj';[string[]]$foldersToIgnore='ThirdParty';Get-ChildItem .\ -Include $foldersToRemove -Recurse|Where-Object{$_.FullName -inotmatch "\\$($foldersToIgnore -join '|')\\"}|Remove-Item -Force -Recurse -WhatIf(虽然这里有点乱 :))
@ChrisJ 考虑在您的解决方案中添加新答案。
C
Community

这对我有用:

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

基于 superuser.com 上的 this answer


很棒,而且易于扩展。我用于 /d /r 。 %%d in (bin,obj,App_Data,packages) do @if exists "%%d" rd /s/q "%%d"
@ParoX 您需要在 .bat 文件中运行它
d
doblak

我写了 a powershell script 来做到这一点。

优点是它会打印出已删除文件夹的摘要,如果您指定了要忽略的任何子文件夹层次结构,则会打印出忽略的文件夹。

https://i.stack.imgur.com/60MpJ.png


+1 非常好!刚刚发现我们实际上可以像 Window Power Shell 中的全取调试器一样调试和查看变量!
我喜欢这个解决方案。我不必乱用 Visual Studio,我可以在需要的时候运行它。非常好!
完全适合我的需求,但我不确定为什么这不能成为一个要点而不是一个完整的回购。 :-)
干得好!我会省略所有目录扫描,因为当您有数千个子目录时,这可能会很慢。仅用于统计的价格太高:-)。另外我会将 $_ -notmatch 'node_modules' 条件添加到 $FoldersToRemove 变量定义
除了 Tomino 的建议之外,我建议排除 packages 文件夹。这是更新后的列表 $FoldersToRemove = Get-ChildItem .\ -include bin,obj -Recurse |其中 {$_ -notmatch 'tools' -and $_ -notmatch '_build' -and $_ -notmatch 'node_modules' -and $_ -notmatch 'packages'} | foreach {$.fullname}
D
Dan Atkinson

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

<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 文件,因为您无法在它们上调用自定义目标,或者您知道解决方法吗
@PiotrOwsiak 是的,您需要在您拥有 .sln 的同一目录中创建文件“before.MySlnFileName.sln.targets”并将您的目标定义放在那里
您可以将 AfterTargets="Clean" 作为属性添加到 Target,它将在 Clean 之后自动调用,在进行重建时直接或间接调用
K
Kdefthog

没有什么对我有用。我需要删除 bin 和 obj 文件夹中的所有文件以进行调试和发布。我的解决方案:

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

2.插入

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

3.保存,重新加载项目,右键clean and presto。


F
Frederik Struck-Schøning

注意:这是一个旧答案,可能需要对 VS 2019 的较新版本和一些 obj 工件进行调整。在使用这种方法之前,请确保 VS 在您的目标和输出目录中不需要任何东西来成功构建。

在干净的目标之后,这样的事情应该以一种非常优雅的方式完成:

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

在 VS2019 中,我发现这会使 IDE 挂起很长一段时间,并且 Rebuild 和 project.assets.json 存在问题
谢谢马蒂亚斯,我添加了一个警告。我想这取决于项目类型,完全清理某些项目可能不是一个好主意。应该有一个调整。
V
Vedran Mandić

一种非常快速且轻松的方法是使用 rimraf npm 实用程序,首先在全局范围内安装它:

> npm i rimraf -g

然后来自项目根目录的命令非常简单(可以保存到脚本文件中):

projectRoot> rimraf **/bin **/obj

要优化所需的效果,您可以利用文档中指定的项目事件目标(您可以使用的是 BeforeRebuild 并使其运行上一个命令):https://docs.microsoft.com/en-us/visualstudio/msbuild/how-to-extend-the-visual-studio-build-process?view=vs-2017

我喜欢 rimraf 实用程序,因为它是跨平台的并且非常快。但是,如果您决定使用目标事件选项,也可以使用 .csproj 中的 RemoveDir 命令。 RemoveDir 方法在@Shaman 的另一个答案中得到了很好的解释:https://stackoverflow.com/a/22306653/1534753


也可以在 Mac 上工作!
是的(几乎?)NodeJS/npm 无处不在……哈哈。
恕我直言,如果您正在使用类似 Unix 的操作系统,例如 Linux、macOS,那么您实际上不需要 rimraf。 rm -rf **/bin **/obj 会做同样的事情。但是,值得提醒的是,如果您的项目位于更深层次的子目录中,则两种解决方案都不会删除这些项目的 bin/obj 目录。所以这个解决方案适用于大多数场景,但不是所有场景。
I
Igor

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

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

这是文章:How to remove bin and/or obj folder before the build or deploy


不过,您只想在重建时执行此操作。除非您希望每个构建都是重建!
A
Aboo

非常类似于 Steve 的 PowerShell 脚本。我刚刚添加了 TestResults 和包,因为大多数项目都需要它。

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

A
Alper Ebicoglu

这是我用于递归删除所有 BIN 和 OBJ 文件夹的批处理文件。

创建一个空文件并将其命名为 DeleteBinObjFolders.bat 将以下代码复制粘贴到 DeleteBinObjFolders.bat 将 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

我只是将此脚本放在我的桌面上 - 但在第一行之后添加了行 cd C:\Git\Workspace...
请注意,/r 优先于 /d,因此名为“bin”和“obj”的文件也可能会被删除。 FOR 命令具有离散的“模式”。 R 和 D 是这些模式的示例,其中只有一个在任何给定时间处于活动状态。
h
habakuk

看看 CleanProject,它将删除 bin 文件夹、obj 文件夹、TestResults 文件夹和 Resharper 文件夹。源代码也可用。


该项目似乎已移至此处:code.msdn.microsoft.com/windowsdesktop/…
C
Community

来自Using Windows PowerShell to remove obj, bin and ReSharper folders

Robert H answer 非常相似,语法更短

运行 powershell cd(change dir) 到项目文件夹的根目录粘贴并在脚本目录下运行。\ -include bin,obj,resharper* -recurse | foreach($) { rd $_.fullname –Recurse –Force}


C
Community

Here is the answer 我回答了一个类似的问题,简单、容易、效果很好,除了 Visual Studio 已有的功能外,不需要其他任何东西。

正如其他人已经响应的那样,Clean 将删除构建生成的所有工件。但它会留下其他一切。

如果您在 MSBuild 项目中有一些自定义,这可能会带来麻烦并留下您认为应该删除的东西。

您可以通过在 .*proj 靠近末尾的某处添加一个简单的更改来规避此问题:

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

这将删除当前平台/配置的 bin 文件夹中的所有内容。


t
tetralobita

我对 Robert H 稍作修改,它会跳过错误并打印删除文件。我通常还会清除 .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

git clean -dfx 是完美的
P
Paul Hatcher

VS 2019/VS 2022 中,这是唯一合理的解决方案。

在解决方案文件夹(.sln 文件所在的位置)中,创建一个名为 Directory.Build.props 的文件并添加编辑它,如下所示。阅读有关此特殊文件 here 的信息。

目录.Build.props

<Project>
  <Target Name="RemoveObjAndBinFolders" AfterTargets="Clean">
    <PropertyGroup>
      <ObjFolder>$(ProjectDir)$(BaseIntermediateOutputPath)</ObjFolder>
      <BinFolder>$(ProjectDir)$(BaseOutputPath)</BinFolder>

      <!-- Microsoft.NET.Sdk.Web sets $(BaseIntermediateOutputPath) to -->
      <!-- an absolute path. Not fixed up to MsBuild 17! -->
      <BaseIntermediateOutputPathFix Condition="$(BaseIntermediateOutputPath.StartsWith($(MSBuildProjectDirectory)))">$([MSBuild]::MakeRelative(
        $(ProjectDir),
        $(BaseIntermediateOutputPath)
      ))</BaseIntermediateOutputPathFix>
    
      <ObjFolder Condition="$(BaseIntermediateOutputPath.StartsWith($(MSBuildProjectDirectory)))">$(ProjectDir)$(BaseIntermediateOutputPathFix)</ObjFolder>
    </PropertyGroup>

    <ItemGroup>
      <ObjFiles Include="$(ObjFolder)/*.*"
                Exclude="$(ObjFolder)/project.assets.json" />
      <ObjSubFolders
                Include="$([System.IO.Directory]::GetDirectories('$(ObjFolder)'))" />
    </ItemGroup>
    
    <!-- Remove "obj" sub folders -->
    <RemoveDir Directories="@(ObjSubFolders)" ContinueOnError="true" />
    <!-- Remove "obj" files (keeping necessary asset file)-->
    <Delete Files="@(ObjFiles)" />
    
    <!-- Remove "bin" folders -->
    <RemoveDir Directories="$(BinFolder)" ContinueOnError="true" />
  </Target>
</Project>

无需修改一堆 .csproj 文件。另外,请注意,我不会按照某些人的建议删除 $(TargetDir)。如果 $(OutDir) 已设置为某个自定义目录(常见的做法),这样做可能会削弱构建系统。


需要注意的是,这个解决方案有时会干扰 VS,导致它抱怨缺少 project.assets.json。此后在我的解决方案中将其停用。一些改进是必要的。
B
Brian

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


确实“干净”还不够好。在使用 MEF 时尤其如此。 “干净的解决方案”不会删除您已删除的引用,这可能会在动态加载文件夹的 DLL 时导致问题。
许多“在我的机器上工作”错误是由 bin/obj 文件夹中旧的或意外的东西引起的,这些东西不会通过“清理”来删除。
S
Simeon Pilgrim

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

每个项目构建脚本都负责它的输出/临时目录。这样工作得很好。因此,当我们更改项目并添加新项目时,我们将脚本基于工作脚本,您会注意到删除阶段并处理它。

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


有时我只需要确保所有构建都是全新的。我不能相信这样做的干净解决方案。删除 bin 和 obj 通常被证明更可靠
对我们来说,只有来自“构建机器”的构建被测试或用于生产,所以开发人员没有必须是“所有干净”类型的问题,构建服务器可以做到这一点。也意味着不需要任何开发人员来进行完整构建。
用 nant 最简单的方法是什么?我有几十个项目的层次结构,我不想在删除脚本上出错。 =)
我们构建了许多可执行文件/dll“资产”,因此每个资产我们都有一个构建它的 nant 脚本。对于每一个,都有一个 Delete 部分,我们在其中为要删除的每个 debug/release bin/obj 目录放置一行。
J
Juozas Kontvainis

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

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

对于 C++ 项目

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

J
Joel Martinez

http://vsclean.codeplex.com/

查找 Visual Studio 解决方案并在其上运行 Clean 命令的命令行工具。这使您可以清理硬盘上所有旧项目的 /bin/* 目录


K
KL XL

您实际上可以进一步考虑 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 参数,因此如果您对第一次运行的列表感到满意,请将其删除。


k
kalalele

上面的几个解决方案给出了如何排除文件夹的答案,但不是在 cmd 中。扩展 Steve Willcock's answer,排除例如其中可能包含 bin 文件夹的 node_modules 文件夹,可以使用下面的扩展单行。

FOR /F "tokens=*" %G IN ('DIR /B /AD /S bin obj ^|find ^"node_modules^" /v /i') DO RMDIR /S /Q "%G"

正如其他人所指出的,如果将上述命令放在 cmd 脚本中并且不直接在命令行中使用它,请将 %G 替换为 %%G


p
pj4533

我们有一个包含许多项目文件的大型 .SLN 文件。我开始制定所有非源代码控制文件所在的“ViewLocal”目录的策略。该目录内部是一个“Inter”和一个“Out”目录。分别用于中间文件和输出文件。

这显然可以很容易地转到您的“viewlocal”目录并进行简单的删除,以摆脱一切。

在你花时间想办法用脚本解决这个问题之前,你可能会考虑设置类似的东西。

不过我不会撒谎,事实证明,在大型组织中维持这样的设置……很有趣。尤其是当您使用像 QT 这样的技术来处理文件和创建非源代码控制的源文件时。但那是另一个故事了!


S
ShivanandSK

考虑到 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 }

x
xianyi

对于批量解决方案。我正在使用以下命令:

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

https://i.stack.imgur.com/knj0w.png


@IF EXIST %%G IF %%~aG geq d 用于检查路径是否存在,路径是文件夹而不是文件。
M
Mudit Sharma

这对我来说很好:开始 /d /r 。 %%d in (bin,obj, ClientBin,Generated_Code) do @if exists "%%d" rd /s /q "%%d"


H
Hacko

我使用带有这个逗号的 .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"

d
dr. evil

我认为您可以右键单击您的解决方案/项目,然后单击“清理”按钮。

据我记得它是这样工作的。我现在没有 VS.NET,所以无法测试它。


这是正确的,也是迄今为止所有建议的解决方案中最简单和最容易的(假设它适合特定情况......)
对不起,但这根本不是真的。它不会删除作为问题根源的 /obj 的内容。至少这是 VS 2013 update 3 的情况。
VS2013 update 4 也有同样的问题。(注意:VS2010 运行良好)
请参阅此答案(关于同一个问题)以获得更好的解释:stackoverflow.com/a/18317221/374198