我处理多个项目,我想递归删除所有名为“bin”或“obj”的文件夹,这样我确信所有项目都会重建所有内容(有时这是迫使 Visual Studio 忘记所有关于以前的构建)。
有没有一种快速的方法来完成这个(例如使用 .bat 文件)而无需编写 .NET 程序?
这取决于您喜欢使用的外壳。
如果您在 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 答案归功于他而不是我 :)
当然,明智的做法是先在安全的地方运行您选择的任何命令来测试它!
我找到了这个线程并得到了宾果游戏。多一点搜索发现了这个强大的 shell 脚本:
Get-ChildItem .\ -include bin,obj -Recurse | ForEach-Object ($_) { Remove-Item $_.FullName -Force -Recurse }
考虑到我在看这里时没有找到答案,我想我会分享。
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
(虽然这里有点乱 :))
这对我有用:
for /d /r . %%d in (bin,obj) do @if exist "%%d" rd /s/q "%%d"
基于 superuser.com 上的 this answer
我写了 a powershell script 来做到这一点。
优点是它会打印出已删除文件夹的摘要,如果您指定了要忽略的任何子文件夹层次结构,则会打印出忽略的文件夹。
https://i.stack.imgur.com/60MpJ.png
$_ -notmatch 'node_modules'
条件添加到 $FoldersToRemove
变量定义
我过去总是在我的解决方案中添加一个新目标来实现这一目标。
<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
没有什么对我有用。我需要删除 bin 和 obj 文件夹中的所有文件以进行调试和发布。我的解决方案:
1.右键项目,卸载,再次右键编辑,到底部
2.插入
<Target Name="DeleteBinObjFolders" BeforeTargets="Clean">
<RemoveDir Directories="..\..\Publish" />
<RemoveDir Directories=".\bin" />
<RemoveDir Directories="$(BaseIntermediateOutputPath)" />
</Target>
3.保存,重新加载项目,右键clean and presto。
注意:这是一个旧答案,可能需要对 VS 2019 的较新版本和一些 obj 工件进行调整。在使用这种方法之前,请确保 VS 在您的目标和输出目录中不需要任何东西来成功构建。
在干净的目标之后,这样的事情应该以一种非常优雅的方式完成:
<Target Name="RemoveObjAndBin" AfterTargets="Clean">
<RemoveDir Directories="$(BaseIntermediateOutputPath)" />
<RemoveDir Directories="$(TargetDir)" />
</Target>
一种非常快速且轻松的方法是使用 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
rm -rf **/bin **/obj
会做同样的事情。但是,值得提醒的是,如果您的项目位于更深层次的子目录中,则两种解决方案都不会删除这些项目的 bin/obj 目录。所以这个解决方案适用于大多数场景,但不是所有场景。
要在构建添加到项目文件之前删除 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
非常类似于 Steve 的 PowerShell 脚本。我刚刚添加了 TestResults 和包,因为大多数项目都需要它。
Get-ChildItem .\ -include bin,obj,packages,TestResults -Recurse | foreach ($_) { remove-item $_.fullname -Force -Recurse }
这是我用于递归删除所有 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
...
看看 CleanProject,它将删除 bin 文件夹、obj 文件夹、TestResults 文件夹和 Resharper 文件夹。源代码也可用。
来自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}
Here is the answer 我回答了一个类似的问题,简单、容易、效果很好,除了 Visual Studio 已有的功能外,不需要其他任何东西。
正如其他人已经响应的那样,Clean 将删除构建生成的所有工件。但它会留下其他一切。
如果您在 MSBuild 项目中有一些自定义,这可能会带来麻烦并留下您认为应该删除的东西。
您可以通过在 .*proj 靠近末尾的某处添加一个简单的更改来规避此问题:
<Target Name="SpicNSpan"
AfterTargets="Clean">
<RemoveDir Directories="$(OUTDIR)"/>
</Target>
这将删除当前平台/配置的 bin 文件夹中的所有内容。
我对 Robert H 稍作修改,它会跳过错误并打印删除文件。我通常还会清除 .vs
、_resharper
和 package
文件夹:
Get-ChildItem -include bin,obj,packages,'_ReSharper.Caches','.vs' -Force -Recurse | foreach ($_) { remove-item $_.fullname -Force -Recurse -ErrorAction SilentlyContinue -Verbose}
另外值得注意的是 git
命令清除所有更改,包括被忽略的文件和目录:
git clean -dfx
在 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)
已设置为某个自定义目录(常见的做法),这样做可能会削弱构建系统。
project.assets.json
。此后在我的解决方案中将其停用。一些改进是必要的。
“干净”还不够好吗?请注意,您可以从命令行使用 /t:clean 调用 msbuild。
在我们的构建服务器上,我们通过 nant 脚本显式删除 bin 和 obj 目录。
每个项目构建脚本都负责它的输出/临时目录。这样工作得很好。因此,当我们更改项目并添加新项目时,我们将脚本基于工作脚本,您会注意到删除阶段并处理它。
如果您在逻辑开发机器上执行此操作,我会像其他人提到的那样坚持通过 Visual Studio 进行清理。
我实际上讨厌乱扔源代码树的 obj 文件。我通常设置项目,以便它们在源代码树之外输出 obj 文件。对于我通常使用的 C# 项目
<IntermediateOutputPath>..\..\obj\$(AssemblyName)\$(Configuration)\</IntermediateOutputPath>
对于 C++ 项目
IntermediateDirectory="..\..\obj\$(ProjectName)\$(ConfigurationName)"
您实际上可以进一步考虑 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 参数,因此如果您对第一次运行的列表感到满意,请将其删除。
上面的几个解决方案给出了如何排除文件夹的答案,但不是在 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
。
我们有一个包含许多项目文件的大型 .SLN 文件。我开始制定所有非源代码控制文件所在的“ViewLocal”目录的策略。该目录内部是一个“Inter”和一个“Out”目录。分别用于中间文件和输出文件。
这显然可以很容易地转到您的“viewlocal”目录并进行简单的删除,以摆脱一切。
在你花时间想办法用脚本解决这个问题之前,你可能会考虑设置类似的东西。
不过我不会撒谎,事实证明,在大型组织中维持这样的设置……很有趣。尤其是当您使用像 QT 这样的技术来处理文件和创建非源代码控制的源文件时。但那是另一个故事了!
考虑到 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 }
对于批量解决方案。我正在使用以下命令:
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
用于检查路径是否存在,路径是文件夹而不是文件。
这对我来说很好:开始 /d /r 。 %%d in (bin,obj, ClientBin,Generated_Code) do @if exists "%%d" rd /s /q "%%d"
我使用带有这个逗号的 .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"
我认为您可以右键单击您的解决方案/项目,然后单击“清理”按钮。
据我记得它是这样工作的。我现在没有 VS.NET,所以无法测试它。
npm install
来重新填充 bin 文件夹。