检测文件是不是在批处理文件中打开

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并且脚本从头开始。

【讨论】:

任何解释这是做什么的?如何调用或使用它?请问可以翻译成英文吗?

以上是关于检测文件是不是在批处理文件中打开的主要内容,如果未能解决你的问题,请参考以下文章

如何检测PDF文档是不是损坏了?

在VC里如何检查一个文件是不是存在

无论用户是不是登录,任务计划程序在设置为运行时都无法打开批处理文件

批处理:打开特定程序中的特定文件?

06 文件处理

如何检查端口是不是在带有批处理文件且没有第三方软件的远程服务器上打开? [关闭]