Detecting if a file is open in a batch file
Asked Answered
G

3

8

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.

I want to check if the EXE is open at the start of 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%.

What's a non-destructive way of checking for an open file that sets %ErrorLevel% to a non-zero value?

Greegree answered 6/8, 2011 at 22:34 Comment(0)
D
10

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.

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).

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:

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.

Devastate answered 7/8, 2011 at 1:25 Comment(1)
Thanks @Andriy. Yep, that works. It can take a little while though, if the executables involved are large, which mine are. The other way I thought of was to write a 2-line delphi utility that tries to rename a file to a random name, and renames it back again if it was successful, and returns a zero exit code if it couldn't.Greegree
S
2
@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.

Sitdown answered 25/6, 2014 at 8:14 Comment(1)
Any explanation what this does? How to call it or use it? Could you translate it to English please?Heger
S
2

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

Sitdown answered 29/2, 2016 at 9:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.