如何以编程方式关闭给定文件夹下的所有文件句柄?

Ame*_*ina 20 windows

我想知道是否有一个命令行工具可以让我关闭在特定文件夹下打开的所有文件句柄。

我尝试过ProcessExplorerUnlocker和类似的工具,但它们提供了 GUI 界面,并且在编程环境中没有用

在 Python、cmd 或 PowerShell 上的解决方案将是理想的。

小智 11

谢谢你。我们在打开文件句柄方面遇到了一些问题,导致 git checkouts 在我们基于 Windows 的 Jenkins 作业中失败,这有助于轻松纠正问题。我将抛出该技术的基础知识:

  1. 在构建节点上安装 Handle.exe。我从这里下载它http://technet.microsoft.com/en-us/sysinternals/bb896655,解压缩它并将 Handle.exe 放在 C:\Windows\System32 下以确保它在默认的 %PATH% 上可用

  2. 安装 Jenkins pre-scm-buildstep 插件:https ://wiki.jenkins-ci.org/display/JENKINS/pre-scm-buildstep 。这允许我们在 git 插件开始访问可能被锁定的文件之前定义操作。

  3. 将以下批处理命令作为 pre-scm 构建步骤实施:

    @echo off
    echo Cleaning up open file handles from %NODE_NAME%:%WORKSPACE%...
    for /f "tokens=3,6,8 delims=: " %%i in ('Handle /accepteula %WORKSPACE% ^| grep workspace') do echo Releasing file lock on E:%%k & handle -c %%j -y -p %%i
    
    Run Code Online (Sandbox Code Playgroud)

它似乎工作得很好,并且肯定会减少虚假故障。我还会注意到我解决的几个问题:

  • Handler.exe 有一个 EULA,它在第一次运行时必须被接受。如果您在本地系统上下文下将 Jenkins 代理作为服务运行,这将是有问题的,因为您无法以该用户身份登录并手动接受它。当我们尝试从 Jenkins 作业运行它时,该进程只是挂起等待用户输入,并且花了几分钟才找出原因。我通过使用 /accepteula 标志从 Jenkins 作业中运行它解决了这个问题,我建议任何将其作为自动化过程实现的人也这样做。这恰好是 HKEY_CURRENT_USER\Software\Sysinternals\Handle 下的注册表设置,如果您需要为特定用户操作它,您也可以通过 regedit.exe 设置和取消设置它,但命令行选项似乎最简单。

  • Jenkins 批处理步骤插件执行批处理代码,就像它在脚本中一样,而不是作为命令行指令。注意转义(例如 %%i, ^| )。

谢谢!


小智 9

我们使用以下代码段来关闭从用户到我们服务器的文件句柄。您可以修改它以供您使用。

rem close all network files that are locked
for /f "skip=4 tokens=1" %%a in ('net files') do net files %%a /close
Run Code Online (Sandbox Code Playgroud)


Ƭᴇc*_*007 6

Unlocker确实声称它为您提供了这种能力:

  1. 只需右键单击文件夹或文件,然后选择解锁器

    第1步

  2. 如果文件夹或文件被锁定,则会出现一个储物柜列表

    第2步

  3. 只需单击Unlock All即可完成!

我不确定它是否支持命令行使用。

MalwareByte 的 FileAssassin执行类似的操作,并且确实支持命令行使用,因此您应该能够非常轻松地编写脚本。

FileAssassin 的开关


t7t*_*ran 6

我创建了这个小批处理文件以通过我的 Eclipse 自动释放对 xml 文件的所有锁定

@echo off
for /f "tokens=3,6,8 delims=: " %%i in ('handle -p eclipse e:\git\ ^| grep .xml') do echo Releasing %%k & handle -c %%j -y -p %%i
Run Code Online (Sandbox Code Playgroud)

您需要下载该手柄从公用微软网站grep的实用工具的GnuWin32

如果您不需要按文件类型过滤,您可以像这样跳过 grep 部分:

@echo off
for /f "tokens=3,6,8 delims=: " %%i in ('handle -p eclipse e:\git\') do echo Releasing %%k & handle -c %%j -y -p %%i
Run Code Online (Sandbox Code Playgroud)

或者,如果您不需要通过特定程序过滤锁,只需删除 eclipse 进程过滤器:

@echo off
for /f "tokens=3,6,8 delims=: " %%i in ('handle e:\git\') do echo Releasing %%k & handle -c %%j -y -p %%i
Run Code Online (Sandbox Code Playgroud)

请记住替换e:\git\为您的文件夹路径。


del*_*ttg 5

如果您使用PSTools,这将强制递归关闭所有打开的文件:

psfile \\serverName c:\path\toDatabase\ -c

请注意,这c:\path\toDatabase\是 C: 驱动器\\serverName,而不是您的本地计算机。起初这对我来说不清楚,所以我想我会指出来。

这是一种几乎肯定会丢失数据的蛮力方法,因此请谨慎使用。

我们有一个拼凑得很厉害的 Access 数据库,它确实让我们的公司定期陷入困境(就在昨天我不得不修复它三遍)。

通常处理这个问题的人休假了几个星期,他的指示使用基于 UI 的方法(开始 > 计算机 > 管理 > 计算机管理(本地)> 连接到另一台计算机 > 系统工具 > 共享文件夹 > 打开文件 > 关闭打开文件)。当我可以运行上述命令并将整个公司从所有数据库文件中踢出并启动压缩和修复过程(我也在研究一种蛮力脚本方法)时,点击太多了。

诀窍是领先于那些在数据库出现故障时立即开始重新连接到数据库的人。他们已经习惯了这一点,以至于他们没有想到要针对它提交错误,他们只是不断地敲打数据库,直到他们重新进入。我只是不断地启动它们,直到我压缩并修复了三打构成数据库的文件。


小智 5

如果您正在讨论通过 Windows 文件服务器(Server 2012 或更高版本)上的 SMB 共享打开的文件句柄,请参阅 PowerShell 答案:

Get-SmbOpenFile | Where-Object { $_.Path -like "D:\Folder\*" } | Close-SmbOpenFile -Force
Run Code Online (Sandbox Code Playgroud)

在较旧的 Windows 文件服务器上,它是openfiles.exe /disconnect.

对于本地系统文件句柄,我发现的最好方法是使用Sysinternals handle.exe