windows 检测文件是否在批处理文件中打开
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6969421/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Detecting if a file is open in a batch file
提问by rossmcm
Say I have a batch file for carrying out a long build and at the end it creates an EXE. If I forget to close the app down before I start the build, the link phase fails when it can't re-create the EXE.
假设我有一个用于执行长时间构建的批处理文件,最后它创建了一个 EXE。如果我在开始构建之前忘记关闭应用程序,链接阶段将在无法重新创建 EXE 时失败。
I want to check if the EXE is open at the startof the build. I tried renaming the EXE file to itself but although this gives an access denied error the rename command (being an internal command) doesn't set %ErrorLevel%.
我想在构建开始时检查 EXE 是否打开。我尝试将 EXE 文件重命名为自身,但尽管这会导致访问被拒绝错误,但重命名命令(作为内部命令)并未设置 %ErrorLevel%。
What's a non-destructive way of checking for an open file that sets %ErrorLevel% to a non-zero value?
检查将 %ErrorLevel% 设置为非零值的打开文件的非破坏性方法是什么?
回答by Andriy M
The rename method didn't work for me (tested on Windows XP SP3). I started an arbitrary application and tried to rename it to itself. There was no error, no effect whatsoever.
重命名方法对我不起作用(在 Windows XP SP3 上测试)。我启动了一个任意应用程序并尝试将其重命名为自身。没有错误,没有任何影响。
However, this method did work:
但是,这种方法确实有效:
COPY /B app.exe+NUL app.exe
When the application was running, this command produced me an error message. And when the application was unengaged, not only this command preserved the contents of file, but it also left the modification timestamp unchanged.
当应用程序运行时,这个命令产生了一条错误信息。并且当应用程序未启动时,该命令不仅保留了文件的内容,而且还保留了修改时间戳不变。
If I were you, therefore, I would probably use this command (at the beginning of the batch script, like you said) in this way:
因此,如果我是您,我可能会以这种方式使用此命令(在批处理脚本的开头,如您所说):
COPY /B app.exe+NUL app.exe >NUL || (GOTO :EOF)
The ||
operator passes the control to the command/block next to it if the previous command has failed (raised the errorlevel value). Therefore, the above command would terminate the script if COPY failed (which it would if the file was open).
||
如果前一个命令失败(提高错误级别值),操作员将控制权传递给它旁边的命令/块。因此,如果 COPY 失败(如果文件已打开),上述命令将终止脚本。
The error message would be preserved (because such messages are usually sent to the so called standard error device and are not discarded with the >NUL
redirection, while other, non-error messages are typically sent to the standard output and so can be suppressed with >NUL
) and serve as an explanation of the premature termination of the script. However, if you want to display your own message instead, you can try something like this:
错误消息将被保留(因为这些消息通常被发送到所谓的标准错误设备并且不会被>NUL
重定向丢弃,而其他非错误消息通常被发送到标准输出,因此可以被抑制>NUL
)和作为脚本提前终止的解释。但是,如果您想显示自己的消息,可以尝试以下操作:
COPY /B app.exe+NUL app.exe >NUL 2>NUL || (ECHO Target file inaccessible& GOTO :EOF)
While >NUL
hides whatever is sent to the standard output, 2>NUL
does the same for the standard error.
虽然>NUL
隐藏了发送到标准输出的任何内容,2>NUL
但对标准错误也一样。
回答by Van De Wack
@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
renames file to the same name, if possible the script jumps to end whichs exit the code, otherwize it produces error code1 and jumps to errorline, after a timeout of 5 seconds it jumps to :start and script starts from beginning.
将文件重命名为相同的名称,如果可能,脚本会跳转到退出代码的结尾,否则它会产生错误代码 1 并跳转到错误行,超时 5 秒后它会跳转到 :start 并且脚本从头开始。
回答by Van De Wack
Found a better way:
找到了更好的方法:
:start
timeout /T 5
if exist %1 (
2>nul (
>> %1 (call )
) && (goto ende) || (goto start) ) else ( exit )
:ende
YourCode
This will check every after 5 seconds for "is the file in use" if it its it will start again. if not it turns to ende where you can do your next options
如果它会再次启动,这将每隔 5 秒检查一次“是否正在使用文件”。如果不是,它就会变成你可以做下一个选择的地方