检测文件是不是在批处理文件中打开
Posted
技术标签:
【中文标题】检测文件是不是在批处理文件中打开【英文标题】:Detecting if a file is open in a batch file检测文件是否在批处理文件中打开 【发布时间】:2011-10-21 14:47:35 【问题描述】:假设我有一个用于执行长时间构建的批处理文件,最后它会创建一个 EXE。如果我在开始构建之前忘记关闭应用程序,则链接阶段会在无法重新创建 EXE 时失败。
我想检查 EXE 是否在构建的开始打开。我尝试将 EXE 文件重命名为自身,但尽管这给出了拒绝访问错误,但重命名命令(作为内部命令)没有设置 %ErrorLevel%。
检查将 %ErrorLevel% 设置为非零值的打开文件的非破坏性方法是什么?
【问题讨论】:
【参考方案1】:重命名方法对我不起作用(在 Windows XP SP3 上测试)。我启动了一个任意应用程序并尝试将其重命名为自身。没有错误,没有任何影响。
但是,这种方法确实有效:
COPY /B app.exe+NUL app.exe
当应用程序运行时,此命令产生了一条错误消息。并且当应用程序未使用时,该命令不仅保留了文件的内容,而且还保持修改时间戳不变。
因此,如果我是你,我可能会以这种方式使用这个命令(在批处理脚本的开头,就像你说的那样):
COPY /B app.exe+NUL app.exe >NUL || (GOTO :EOF)
||
运算符将控制权传递给它旁边的命令/块,如果前一个命令失败(提高了错误级别值)。因此,如果 COPY 失败,上述命令将终止脚本(如果文件已打开)。
错误消息将被保留(因为这些消息通常被发送到所谓的标准错误设备并且不会被>NUL
重定向丢弃,而其他非错误消息通常被发送到标准输出等等可以用>NUL
抑制,并作为脚本提前终止的解释。但是,如果您想显示自己的消息,可以尝试这样的操作:
COPY /B app.exe+NUL app.exe >NUL 2>NUL || (ECHO Target file inaccessible& GOTO :EOF)
>NUL
隐藏发送到标准输出的任何内容,2>NUL
对标准错误执行相同操作。
【讨论】:
谢谢@Andriy。是的,这行得通。但是,如果涉及的可执行文件很大(我的很大),则可能需要一些时间。我想到的另一种方法是编写一个 2 行的 delphi 实用程序,尝试将文件重命名为随机名称,如果成功则再次重命名,如果不能,则返回零退出代码。跨度> 【参考方案2】:找到更好的方法:
:start
timeout /T 5
if exist %1 (
2>nul (
>> %1 (call )
) && (goto ende) || (goto start) ) else ( exit )
:ende
YourCode
这将每隔 5 秒检查一次“正在使用的文件”是否会重新启动。如果不是,它会结束,你可以在哪里做你的下一个选择
【讨论】:
【参考方案3】:@echo off
:start
ren filename filename // rename file to same name
if errorlevel 1 goto errorline
echo command successfull file is not in use anymore
goto end
:errorline
echo Rename wasnt possible, file is in use try again in 5seconds
timeout /T 5
goto :start
:end
exit
将文件重命名为相同的名称,如果可能脚本跳转到结束退出代码,否则它会产生错误代码1并跳转到错误行,超时5秒后它会跳转到:start并且脚本从头开始。
【讨论】:
任何解释这是做什么的?如何调用或使用它?请问可以翻译成英文吗?以上是关于检测文件是不是在批处理文件中打开的主要内容,如果未能解决你的问题,请参考以下文章