如何在Visual Studio中完全清除bin和obj文件夹?

147
如果你右键点击一个文件夹,你会看到一个“清理”菜单项。我以为它会清理(删除)obj和bin目录。然而,据我所见,它什么都不做。 还有其他的方法吗? (请不要告诉我去Windows资源管理器或者cmd.exe) 我想删除obj和bin文件夹,以便我可以轻松地压缩整个文件夹。

如果是由CMake(CMakeLists.txt)构建的,则还可以有一个“CMakeSettings.json”文件。对于我来说,这个文件比vcpkg安装子目录高一级。该文件不是项目的.gitignore的一部分,因此对于Ruben的git clean ...方法来说很令人困惑。 - Philip Oakley
22个回答

148

正如其他人已经回答过的,Clean将删除构建生成的所有工件。但它会留下其他所有东西。

如果您在MSBuild项目中进行了一些自定义,则可能会遇到问题,并留下您认为应该删除的内容。

您可以通过向.*proj添加以下内容来解决此问题:

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

这将删除当前平台/配置下bin文件夹中的所有内容。
------编辑 根据下面Shaman的答案的轻微改进(分享投票并给他一些)。
<Target Name="SpicNSpan"  AfterTargets="Clean">
    <!-- Remove obj folder -->
    <RemoveDir Directories="$(BaseIntermediateOutputPath)" />
    <!-- Remove bin folder -->
    <RemoveDir Directories="$(BaseOutputPath)" />
</Target>

---- 再次编辑,加入了xDisruptor的部分,但我删除了.vs文件夹,因为最好在.gitignore(或等效文件)中处理。

已更新至VS 2015。

<Target Name="SpicNSpan" AfterTargets="Clean"> <!-- common vars https://msdn.microsoft.com/en-us/library/c02as0cs.aspx?f=255&MSPPError=-2147217396 -->
     <RemoveDir Directories="$(TargetDir)" /> <!-- bin -->
     <RemoveDir Directories="$(ProjectDir)$(BaseIntermediateOutputPath)" /> <!-- obj -->
</Target>

他还提供了一个很好的建议,如果你有多个项目需要推进,可以使任务更容易部署和维护。
如果您投票支持此答案,请确保同时投票支持它们两个。

23
这是最佳解决方案,有效且不需要特殊工具,确保每个团队成员都使用相同的“清除”方法。为什么 MS Visual Studio 无法正确清理完全是个谜。 - Rolf
1
这绝对是最容易实现的解决方案,可以在没有任何外部插件的情况下完成工作。 - tomoguisuru
1
不确定如何激活/调用此目标。 只是选择“清理”似乎没有任何作用。 那么我该如何使用它? - aliceraunsbaek
5
默认情况下,Visual Studio没有完全清理干净是因为微软必须支持多个项目输出到同一个目录的情况。如果在清理项目时默认情况下清空其整个输出目录,则可能会清除与该项目无关的文件。因此,默认行为是跟踪实际由构建过程输出的文件,并仅在清理时删除这些文件。在清理时常见的一类错误是在构建过程中创建或复制文件而没有告诉MSBuild将其添加到跟踪列表中。 - Tim Sparkles
1
这个答案会导致.Net Core出现问题。下次尝试编译时,会出现错误“未找到资源文件'c:\whatever\project.assets.json'。运行NuGet软件包还原以生成此文件。”为避免这种情况,不要添加删除obj文件夹的行。 - Steve Smith
显示剩余8条评论

89

如果你正在使用Git,并且在你的项目中有一个正确的.gitignore文件,那么你可以:

git clean -xdf --dry-run

要完全删除 .gitignore 列表中的所有文件,即它将清除 objbin 文件夹(x 触发此行为)。


注意: 参数 --dry-run 仅模拟操作("Would remove ..."),并向您显示 git 实际上将删除哪些内容。先用 dry-run 进行尝试,然后去掉参数就能真正删除文件和文件夹。

此命令执行完后,您可以使用 dotnet restore mySolution.sln 来恢复所有 NUGET 包。如果您已经打开了开发人员控制台,那么您还可以快速运行 msbuild -m mySolution.sln(无需打开 Visual Studio)以查看是否成功。


4
非常好用。当你想在整个解决方案中执行操作而不仅仅是一个 Visual Studio 项目时,这非常方便。 - Ehtesh Choudhury
@JoeHealy,与其先清理再压缩,使用git-archive直接从代码库中进行压缩可能更容易。 - Reinier Torenbeek
据我理解,-xdf-d -f -x 的意思是相同的,但我只能通过 git clean -d -f -x 命令获得成功的结果。当我使用 -xdf 时,它只会显示 Would remove \somedirectory。有人可以解释一下吗? - mkb
3
好的,现在我明白了;关键是 --dry-run,这只会告诉你哪些文件将被删除。不错。 - mkb
3
这将删除所有内容,包括.vs文件夹、.suo文件、packages文件夹等。通常你不想要那些。我只想让binobj消失。 - nawfal
显示剩余6条评论

57

对于 Visual Studio 2015,MSBuild 变量已略有变化:

  <Target Name="SpicNSpan" AfterTargets="Clean"> <!-- common vars https://msdn.microsoft.com/en-us/library/c02as0cs.aspx?f=255&MSPPError=-2147217396 -->
         <RemoveDir Directories="$(TargetDir)" /> <!-- bin -->
         <RemoveDir Directories="$(SolutionDir).vs" /> <!-- .vs -->
         <RemoveDir Directories="$(ProjectDir)$(BaseIntermediateOutputPath)" /> <!-- obj -->
  </Target>
请注意,此代码片段还会从解决方案的根目录中清除.vs文件夹。如果您认为删除.vs文件夹过度了,则可以将相关行注释掉。我启用了它,因为我注意到在某些第三方项目中,如果在.vs文件夹内存在application.config等文件,会导致问题。
补充说明:
如果您关心解决方案的可维护性优化,您可能希望更进一步并将上述代码片段放入一个单独的文件中,如下所示:
  <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
       <Target Name="SpicNSpan" AfterTargets="Clean"> <!-- common vars https://msdn.microsoft.com/en-us/library/c02as0cs.aspx?f=255&MSPPError=-2147217396 -->
            <RemoveDir Directories="$(TargetDir)" /> <!-- bin -->
            <RemoveDir Directories="$(SolutionDir).vs" /> <!-- .vs -->
            <RemoveDir Directories="$(ProjectDir)$(BaseIntermediateOutputPath)" /> <!-- obj -->
       </Target>
  </Project>

然后在每个*.csproj文件的最后都像这样包含此文件:

     [...]
     <Import Project="..\..\Tools\ExtraCleanup.targets"/>
  </Project>
这样,您就可以集中在一个地方丰富或微调额外的清理逻辑,而不必每次想要改进时手动编辑每个*.csproj文件,避免繁琐的工作。

1
@progLearner 当然有,https://dev59.com/aWLVa4cB1Zd3GeqPvVQ7#10019708 - XDS
1
@progLearner 这是一个棘手的问题,需要正确回答。有些文件似乎被锁定了,但如果我们坚持2或3次,它们就会被删除。然后还有一些情况,文件确实被锁定了,这时你就没办法了,除非你杀死锁定它们的进程,否则你无法删除它们。如果你处于方案#1,则可以尝试使用最新的MSBuildCommunityTasks中的delete-directory操作,该操作具有persist-delete标志(您可以阅读有关此操作的文档,因为它超出了本特定线程的范围)。 - XDS
1
我曾经遇到过类似的问题。有一个名为VSCompiler.exe或类似名称的后台进程正在运行。在删除目录之前,您可以尝试先结束此进程,然后查看是否有效(我认为会有效)。祝你好运! - XDS
1
虽然这是正确的,但似乎会在重新加载项目之前破坏NuGet。 - HackSlash
1
导入代码片段的另一个巨大优势是,您可以在项目加载后修改ExtraCleanup.targets。这在测试代码片段时非常有用。 - Ama
显示剩余7条评论

47

在构建项目之前删除bin和obj,请在项目文件中添加以下内容:

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

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


4
我也喜欢去掉中间环节的想法,但是在使用 BeforeBuild 的时候会产生重大的副作用,因为它会清除所有进行增量构建的可能性。对于需要较长时间来构建的项目,这是一个停工的问题。此外,通过清除基本输出目录,您可能会干扰希望执行多目标/配置构建并在打包部署之前累计结果的工具,在这种情况下,只有最后一次生成的结果会被保留。 - Newtopian

27

这个网站:https://sachabarbs.wordpress.com/2014/10/24/powershell-to-clean-visual-studio-binobj-folders/ 使用William Kempf的PowerShell命令从当前目录和子目录中删除任何bin和obj文件夹。 它应该可以从驱动器的根目录运行。

这是William的版本

 gci -inc bin,obj -rec | rm -rec -force

以下是William的原话:

这会删除当前目录及其每个子目录中的所有“bin”和“obj”目录。在工作区目录中运行它可使状态变得“干净”,尤其是当有人弄乱了事情,而IDE中的“清理”或“重建”无法解决时,这非常有用。

对于那些可能不知道的读者,PowerShell支持命令别名,在这里我将其重新编写,没有使用别名。

Get-ChildItem -inc bin,obj -rec | Remove-Item -rec -force

注意:你应该将这个保存在一个 PowerShell 文件中,并将该文件放在解决方案的根目录下(即 .sln 文件所在的位置),然后在需要进行适当的清理时运行它(而不是 VisualStudio 执行的那种 Mickey Mouse 清理,它也会报告成功)。


请注意,如果您使用像Mercurial这样的版本控制系统,并且它与此脚本处于同一目录级别,则此脚本将损坏您的存储库,如果您在其中一个“bin”文件夹中存储任何内容...否则,这是一个非常有用的脚本! - Loudenvier

12

请查看Ron Jacobs出色的开源CleanProject,如果您愿意,它甚至可以负责压缩。

这是CodePlex的链接


8

Visual Studio扩展

enter image description here

右键解决方案 - 选择“删除bin和obj文件夹”


现在VS2022有一个不同的扩展名:“Clean Bin and Obj” https://marketplace.visualstudio.com/items?itemName=dobrynin.cleanbinandobj - Alexander Puchkov

4
您可以轻松地在Far Manager中找到并删除bin和obj文件夹。
1. 导航到您的解决方案,按下Alt + F7键 2. 在搜索设置对话框中: - 在“A file mask or several file masks”字段中输入“bin,obj” - 选择“Search for folders”选项 - 按Enter 3. 搜索完成后,切换到“Panel”视图。 4. 选择所有文件(使用Ctrl + A),然后删除文件夹(按“Shift + Del”)。
希望这能帮助到某些人。

3
我在谷歌上搜索了这个问题,寻找自动解决方案,特别是停止手动在 FAR 管理器中执行它。 - Vlad

3

根据Joe的答案,我已经将VB代码转换成C#:

/// <summary>
/// Based on code of VSProjCleaner tool (C) 2005 Francesco Balena, Code Archirects
/// </summary>
static class VisualStudioCleaner
{
    public static void Process(string rootDir)
    {
        // Read all the folder names in the specified directory tree
        string[] dirNames = Directory.GetDirectories(rootDir, "*.*", SearchOption.AllDirectories);
        List<string> errorsList = new List<string>();

        // delete any .suo and csproj.user file
        foreach (string dir in dirNames) {
            var files = new List<string>();
            files.AddRange(Directory.GetFiles(dir, "*.suo"));
            files.AddRange(Directory.GetFiles(dir, "*.user"));
            foreach (string fileName in files) {
                try {
                    Console.Write("Deleting {0} ...", fileName);
                    File.Delete(fileName);
                    Console.WriteLine("DONE");
                } catch (Exception ex) {
                    Console.WriteLine();
                    Console.WriteLine(" ERROR: {0}", ex.Message);
                    errorsList.Add(fileName + ": " + ex.Message);
                }
            }
        }

        // Delete all the BIN and OBJ subdirectories
        foreach (string dir in dirNames) {
            string dirName = Path.GetFileName(dir).ToLower();
            if (dirName == "bin" || dirName == "obj") {
                try {
                    Console.Write("Deleting {0} ...", dir);
                    Directory.Delete(dir, true);
                    Console.WriteLine("DONE");
                } catch (Exception ex) {
                    Console.WriteLine();
                    Console.WriteLine(" ERROR: {0}", ex.Message);
                    errorsList.Add(dir + ": " + ex.Message);
                }
            }
        }
        Console.WriteLine(new string('-', 60));
        if (errorsList.Count == 0) {
            Console.WriteLine("All directories and files were removed successfully");
        } else {
            Console.WriteLine("{0} directories or directories couldn't be removed", errorsList.Count);
            Console.WriteLine(new string('-', 60));
            foreach (string msg in errorsList) {
                Console.WriteLine(msg);
            }
        }
    }
}

3
在Windows中打开资源管理器,导航到你的SLN文件夹,点击搜索框并输入kind:=folder;obj --> 对于obj文件夹,使用CTRL+A删除它们 - 对于bin文件夹也是一样。完成。
无需任何工具或额外软件。

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