Windows bat 查找文件被哪个进程占用,并终止该进程

这篇具有很好参考价值的文章主要介绍了Windows bat 查找文件被哪个进程占用,并终止该进程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、背景

我有个批处理脚本如下:

@echo off
chcp 936 & cls
cd /D F:\Chen\python3\ExciseC
set fdate=%date:~0,4%%date:~5,2%%date:~8,2%
python main.py >> crawl_record_%fdate%.log 2>&1
for /F %%f in ('dir crawl_record_*.log /B ^| find /V "%fdate%"') do move %%f archived\logs

其中,for /F语句是将除当天之外的log文件,移动到archived\logs,然后这个批处理是在任务计划中定期跑的。
运行一段时间后,偶尔发现仍有当天之外的log文件未被移动到archived\logs,后来定位发现,文件是被python.exe程序给占用了,推测可能是python main.py >> crawl_record_%fdate%.log 2>&1这个条语句在执行过程中非正常结束(如重启、断网等),导致重定向符后的文件被锁定,然后第2天,这个文件无法正常移动。

然后我的需求出现了:找到占用这个文件的进程,然后杀死它,释放被占用的文件,再进行移动操作该文件。(这些步骤都要在批处理内完成,而非图形界面操作)

二、解决问题

1. 查找占用指定文件的进程pid

这里使用handle.exe命令程序,handle.exeSysinternals Suite中的进程实用程序。
它可用于显示系统中任何进程的打开句柄的信息。可以使用它来查看打开了文件的程序,或者查看程序的所有句柄的对象类型和名称。
帮助文档:https://learn.microsoft.com/en-us/sysinternals/downloads/handle
下载地址:https://download.sysinternals.com/files/Handle.zip
下载并解压出 handle.exe / handle64.exe 应用程序,然后把它放到path环境变量里的某个路径下。

handle /v name /nobanner

/v 使输出结果为逗号分隔符的csv格式,name 要搜索的被进程打开的文件名称(接受片段),/nobanner 不显示启动banner和版权信息。更多信息请查看handle /?帮助信息。

输出结果结构如下所示:

C:\Users\cyinl>handle /v /nobanner crawl_record_20230722.log
Process,PID,Type,Handle,Name
python.exe,23156,File,0x000001E0,F:\test\crawl_record_20230722.log

注意:
tasklist也可以查看进程pid,但是它只能按照 exe/dll 模块名来查找,命令格式:
tasklist /M 模块名,像示例中的crawl_record_20230722.log这种文件,是查不到相关进程的。

2. 终止进程

handle.exe可以终止进程,格式:

handle /nobanner /p PID /c <句柄号>

但是,句柄号不太好拿到,如下:

C:\Users\cyinl>handle /nobanner /p 23156
   40: File          D:\Chen\MySoft\Python\Python3.7.7
  1D0: File          C:\Windows\System32\zh-CN\KernelBase.dll.mui
  1E0: File          F:\test\crawl_record_20230722.log
  208: File          C:\Windows\System32\zh-CN\kernel32.dll.mui

第1行的40,应该就是要关闭的进程文件的句柄号,但是能确保要关闭的就是第1行的句柄号???有些困惑。

taskkill命令也可以终止进程,格式:

taskkill /f /pid <进程号>

/f表示强制终止进程,/pid指定要终止进程的pid进程号
输出结果如下示例:

C:\Users\cyinl>taskkill /f /pid 23156
成功: 已终止 PID 为 23156 的进程。

3. 实现代码

handletaskkill两个命令,改进批处理,来解决问题了。具体实现如下:

@echo off
chcp 936 & cls
cd /D F:\Chen\python3\ExciseC
set fdate=%date:~0,4%%date:~5,2%%date:~8,2%
python main.py >> crawl_record_%fdate%.log 2>&1
for /F %%f in ('dir crawl_record_*.log /B ^| find /V "%fdate%"') do move %%f archived\logs

REM After the above command is executed, if the files are successfully moved, they will not enter the loop of this command
for /F %%f in ('dir crawl_record_*.log /B ^| find /V "%fdate%"') do (
	echo the file to move is locked: %%f
	for /F "skip=1 tokens=2 delims=," %%p in ('handle /v %%f /nobanner') do taskkill /F /PID %%p
	REM If the move command is executed immediately after the process is deleted, it will fail. Therefore, a 5-second delay is given here
	timeout /T 5 /nobreak > nul
	move %%f archived\logs
)

解释:

  1. 如果第1个for /F能正常移动文件的话,就不会进入第2个for /F
  2. 第2个for /F用来查找被占用的log文件,嵌套的第3个for /F获取进程pid,其中skip表示跳过第1行,delims=,表示使用,将数据按列分隔,tokens=2表示取第2列。然后do结构体内使用taskkill命令将查到的pid对应的进程终止掉。
  3. 测试发现,终止进程后,不能立刻去移动文件,否则可能会失败,因此这里用timeout命令给了5秒延时,然后再去移动文件。

三、拓展

手动查找并终止进程

1. 使用系统自带的资源监视器

1)在任务栏搜索资源监视器,切换到CPU选项卡,在关联的句柄-搜索句柄输入框中,输入被占用的文件名称;
2)在搜索结果中,选中需要终止的进程,右键,选择终止进程即可
Windows bat 查找文件被哪个进程占用,并终止该进程,Windows,Batch,windows

2. 使用Process Explorer工具

你也可以使用 Process Explorer ,它是基于handle的GUI版本,Process Explorer可查看有关哪些句柄和DLL进程已打开或加载的信息。
下载地址:https://download.sysinternals.com/files/ProcessExplorer.zip
解压后直接打开procexp.exe/procexp64.exe即可使用。
1)点击搜索图标,输入待查找的文件名称;
2)在搜索结果中,点击搜索结果,会自动定位到相关进程以及文件句柄;
3)右键对应的进程-kill Process 或者 右键对应的文件句柄-close Handle

Windows bat 查找文件被哪个进程占用,并终止该进程,Windows,Batch,windows文章来源地址https://www.toymoban.com/news/detail-606426.html

到了这里,关于Windows bat 查找文件被哪个进程占用,并终止该进程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Windows 通过端口占用查找应用程序

    对于开发人员在启动项目的过程中也许会遇到程序使用 端口被占用的情况;如下: 遇到这种情况我们可以换一个端口,也可以查找是哪个程序暂用了这个端口;在Windows上我们可以通过如下方式去查找对应的端口程序信息。 1、打开dos命令窗口 开始—-运行—-cmd,或者是wind

    2024年02月12日
    浏览(41)
  • Windows下bat脚本启动Java进程cmd中文乱码修复

    建议执行前备份注册表 中文乱码原因: 1、cmd默认展示编码为GBK 2、cmd默认展示字体展示中文会乱码 以下脚本会将cmd窗口字体改为UTF-8,并修改字体为Consolas,需要注意的是,此操作属于永久操作,重新打开cmd即可生效 另外,如需执行条件判断逻辑可以使用 reg query 来先查询出

    2024年02月12日
    浏览(58)
  • Windows BAT批处理字符串相关操作(字符串定义、分割、拼接、替换、切片、查找)

    使用 set 来定义字符串 代码说明: 将字符串Hello赋值给string1的变量 使用 %string1%%string2% 的方式完成字符串的拼接。 代码说明: 用来连接字符串的字符串,如果包含了特殊字符则需要使用 ^ 转义,并且需要使用 \\\"\\\" 括起来,特殊字符包括(但不限于): 符号 作用 @ 命令行回显

    2024年02月12日
    浏览(42)
  • Windows中杀死占用某个端口的进程

            Windows本地微服务并发启动后,断开微服务,重新启动微服务发现端口被占用,网上搜索一些前辈的建议,现在汇总一下,如有误还望大家指正。         第一步:打开dos命令窗         具体是点击起始菜单(或是通过win+R快捷键),在输入框中输入cmd,点击确

    2024年02月11日
    浏览(37)
  • Windows查看端口占用情况及杀掉进程

    目录  1、打开命令窗口(以管理员身份运行)  2、查找所有运行的端口  3、查看被占用端口对应的 PID 4、查看指定 PID 的进程 5、结束进程 开发时经常遇到端口被占用的情况,这个时候我们就需要找出被占用端口的程序,然后结束它。  开始—-运行—-cmd ,或者是  window+R  组

    2024年02月08日
    浏览(66)
  • Windows运行单个.bat文件或运行多个.bat文件

    首先创建一个.bat文件,例如 1.bat  ,进入文件编辑,输入你想做的指令,例如: 进入Anaconda虚拟环境,然后运行代码 CALL E:Anaconda3Scriptsactivate.bat E:Anaconda3 CALL conda activate you_name E: cd tensorrt python main.py 将以上代码输入到  1.bat  文件里, 注意修改路径 ,代码中的 E 是盘符号

    2024年02月05日
    浏览(48)
  • Linux如何查看文件进程占用-lsof

    lsof命令是什么? 可以列出被进程所打开的文件的信息。被打开的文件可以是 1.普通的文件,2.目录  3.网络文件系统的文件,4.字符设备文件  5.(函数)共享库  6.管道,命名管道 7.符号链接 8.底层的socket字流,网络socket,unix域名socket 9.在linux里面,大部分的东西都是被当做文

    2024年02月12日
    浏览(33)
  • windows下根据端口查找PID,杀掉进程

    1、打开命令窗口(以管理员身份运行) 开始—-运行—-cmd 或者 window+R 然后回车 2、查找所有运行的端口 3、查找指定端口对应的PID 4、确认下是否是自己想要查找的进程 5、结束进程 参数解释:/F (强制)

    2024年02月11日
    浏览(43)
  • 【Windows】定时任务执行bat文件失败

    bat双击正常,放在Windows服务器的任务计划程序中执行失败 直接执行bat文件,正常, 运行windows定时任务来执行该bat文件,执行失败 1、copy命令前加 “C:Windowssystem32cmd.exe” /C 2、共享盘需要建立连接 3、不要使用最高权限运行 声明:我猜的 1、大概就是用定时任务没有指定执

    2024年02月15日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包