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

是否有一种快速的方法来实现这一点(例如使用.bat文件),而不必编写。net程序?


当前回答

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

其他回答

上面的几个解决方案给出了如何排除文件夹的答案,但不是在cmd。扩展Steve Willcock的回答,排除例如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。

在VS 2019/VS 2022中,这是唯一明智的解决方案。

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

Directory.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)被设置为某个自定义目录(一种常见的做法),那么这样做可能会使构建系统瘫痪。

我们有一个大的。sln文件与许多项目文件。我开始了一个“ViewLocal”目录的策略,所有非源代码控制的文件都位于这个目录中。该目录中有一个“Inter”和一个“Out”目录。分别用于中间文件和输出文件。

这显然让你很容易去到你的“viewlocal”目录,做一个简单的删除,以摆脱一切。

在花时间研究如何使用脚本解决这个问题之前,您可能会考虑设置一些类似的东西。

我不会说谎,在一个大型组织中维持这样的设置已经证明....有趣。特别是当您使用像QT这样的技术来处理文件和创建非源代码控制的源文件时。但那完全是另一回事了!

我采取了不同的方法来解决这个问题。我没有编写一个脚本来寻找不同位置的所有“obj”和“bin”文件夹,而是直接在构建过程中将这些文件夹分组在一个方便的位置。

在解决方案文件夹中添加一个Directory.Build.props文件,如下所示:

<Project>
    <PropertyGroup>
        <BaseProjectArtifactPath>$(MSBuildThisFileDirectory).artifacts\$(MSBuildProjectName)</BaseProjectArtifactPath>
        <BaseOutputPath>$(BaseProjectArtifactPath)\bin\</BaseOutputPath>
        <BaseIntermediateOutputPath>$(BaseProjectArtifactPath)\obj\</BaseIntermediateOutputPath>
    </PropertyGroup>
</Project>

现在,所有的“bin”和“obj”文件夹将被创建在解决方案根目录下的一个单独的.artifacts文件夹中,而不是各个项目文件夹中。准备好重新开始了吗?只要删除.artifacts文件夹就可以了。

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

每个项目构建脚本都负责它的输出/临时目录。这样做效果很好。因此,当我们更改一个项目并添加一个新项目时,我们将脚本建立在一个工作脚本的基础上,您会注意到删除阶段并照顾它。

如果你是在你的逻辑开发机上做的,我还是会像其他人提到的那样,坚持通过Visual Studio进行清理。