【问题标题】:I want to delete all bin and obj folders to force all projects to rebuild everything我想删除所有 bin 和 obj 文件夹以强制所有项目重建所有内容
【发布时间】:2010-10-19 19:34:16
【问题描述】:

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

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

【问题讨论】:

  • 如果 Build->Clean Solution 真的这样做就好了。

标签: visual-studio visual-studio-2008 batch-file cmd


【解决方案1】:

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

【讨论】:

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

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

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

【讨论】:

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

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

如果您在 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 文件夹。
【解决方案4】:

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

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

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

【讨论】:

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

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

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

对于 C++ 项目

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

【讨论】:

    【解决方案6】:

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

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

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

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

    【讨论】:

      【解决方案7】:

      http://vsclean.codeplex.com/

      查找 Visual 的命令行工具 Studio 解决方案并运行 Clean 对他们下达命令。这让你清洁 所有这些的 /bin/* 目录 你一直在做的旧项目 你的硬盘

      【讨论】:

        【解决方案8】:

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

        <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 之后自动调用,在重建时直接或间接调用
        【解决方案9】:

        我找到了这个帖子并得到了宾果游戏。更多搜索发现了这个强大的 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 考虑在您的解决方案中添加新答案。
        • 这没有按预期工作,我收到很多错误消息,例如:remove-item : Impossible de supprimer l'élément C:\Projects\...: Impossible de trouver une partie du chemin d'accès 'AccessibilityManagerCompat_AccessibilityStateChangeListenerImplementor.class'. + CategoryInfo : WriteError: (AccessibilityMa...plementor.class:FileInfo) [Remove-Item], DirectoryNotFoundException + FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
        【解决方案10】:

        这对我有用:

        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 文件中运行它
        【解决方案11】:

        我写了a powershell script 来做这件事。

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

        【讨论】:

        • +1 非常好!刚刚发现我们实际上可以像 Window Power Shell 中的全取调试器一样调试和查看变量!
        • 我喜欢这个解决方案。我不必乱用 Visual Studio,我可以在需要的时候运行它。非常好!
        • 完全满足我的需求,但我不知道为什么这不能是一个要点,而不是一个完整的回购。 :-)
        • 干得好!我会省略所有目录扫描,因为当您有数千个子目录时,这可能会很慢。仅用于统计的价格太高:-)。另外我会将$_ -notmatch 'node_modules' 条件添加到$FoldersToRemove 变量定义
        【解决方案12】:

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

        【讨论】:

          【解决方案13】:

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

          【讨论】:

          【解决方案14】:

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

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

          1. 运行 powershell
          2. cd(更改目录)到项目文件夹的根目录
          3. 粘贴并在脚本下方运行

            dir .\ -include bin,obj,resharper* -recurse | foreach($) { rd $_.fullname –Recurse –Force}

          【讨论】:

            【解决方案15】:

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

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

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

            您可以通过简单地更改您的 .*proj 来规避这个问题,方法是在接近末尾的某处添加它:

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

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

            【讨论】:

              【解决方案16】:

              在构建添加到项目文件之前删除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

              【讨论】:

              • 不过,您只想在重建时执行此操作。除非您希望每个构建都是重建!
              【解决方案17】:

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

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

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

              【讨论】:

              • 在 VS2019 中,我发现这会使 IDE 挂起很长一段时间,并且 Rebuild 和 project.assets.json 存在问题
              • 感谢 Mattias,我已经添加了警告。我想这取决于项目类型,完全清理某些项目可能不是一个好主意。应该对此进行调整。
              【解决方案18】:

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

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

              2.插入

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

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

              【讨论】:

                【解决方案19】:

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

                【讨论】:

                  【解决方案20】:

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

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

                  【讨论】:

                    【解决方案21】:

                    这是我用于递归删除所有 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
                    

                    【讨论】:

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

                    批量解决。我正在使用以下命令:

                    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. DIR /S /AD /B *obj 将包含不期望的结果(tobj 文件夹)

                    【讨论】:

                    • @IF EXIST %%G IF %%~aG geq d 用于检查路径是否存在,路径是文件夹而不是文件。
                    【解决方案23】:

                    我对@9​​87654321@ 稍作修改,它会跳过错误并打印删除文件。我通常也会清除.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 是完美的
                    【解决方案24】:

                    一种非常快速且轻松的方法是使用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 命令。 @Shaman 在另一个答案中很好地解释了RemoveDir 方法:https://stackoverflow.com/a/22306653/1534753

                    【讨论】:

                      【解决方案25】:

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

                      【讨论】:

                        【解决方案26】:

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

                        【讨论】:

                          【解决方案27】:

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

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

                          Directory.Build.props

                          <Project>
                            <Target Name="RemoveObjAndBinFolders" AfterTargets="Clean">
                              <PropertyGroup>
                                <!-- Microsoft.NET.Sdk.Web sets $(BaseIntermediateOutputPath) to -->
                                <!-- an absolute path. Possibly fixed in MsBuild 16.6? -->
                                <BaseIntermediateOutputPathFix>$([MSBuild]::MakeRelative(
                                  $(ProjectDir),
                                  $(BaseIntermediateOutputPath)
                                ))</BaseIntermediateOutputPathFix>
                              
                                <ObjFolder>$(ProjectDir)$(BaseIntermediateOutputPathFix)</ObjFolder>
                                <BinFolder>$(ProjectDir)$(BaseOutputPath)</BinFolder>
                              </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) 已设置为某个自定义目录(这是常见的做法),这样做可能会削弱构建系统。

                          【讨论】:

                            【解决方案28】:

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

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

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

                            【讨论】:

                              猜你喜欢
                              • 2011-08-17
                              • 2012-07-11
                              • 2018-05-19
                              • 1970-01-01
                              • 1970-01-01
                              • 2018-01-05
                              • 1970-01-01
                              • 2020-11-12
                              • 1970-01-01
                              相关资源
                              最近更新 更多