'Check if file is locked inside a batch file for loop
I have a script that runs through some files and copies them to another location. But the script needs to wait until the file is no longer being written to. I tried all the solutions here:
- How to check in command-line if a given file or directory is locked (used by any process)?
- Process a file after a file is finished being written Windows Command Line .bat
- BATCH - wait for file to be complete before picking up
But the problem is that they don't work when wrapped in a loop. It always says the file is locked. If the script it cancelled and re-run it correctly finds the file unlocked. Am I doing something wrong or is there a trick to make this work?
For locking a test file, checkfile.txt
, I do:
(
>&2 pause
) >> checkfile.txt
Then the example script to check the file is this:
@echo off
for %%i in (*.txt) do (
:loop
ping localhost -n 5 > nul
echo "check if locked"
powershell -Command "$FileStream = [System.IO.File]::Open('%%i', 'Open', 'Write'); $FileStream.Close(); $FileStream.Dispose()" >NUL 2>NUL || (goto :loop)
echo "NOT locked anymore"
)
Solution 1:[1]
You cannot goto
in a loop as it will simply break the for
loop entirely. Additionally, the exit code
or errorlevel
is set for the last successful command. In this case being the powershell
dispose command. Simply do the loop outside of the code block:
@echo off & setlocal
for %%i in (*.txt) do call :loop %%~i
goto :EOF
:loop
powershell -Command "[System.IO.File]::Open('%1', 'Open', 'Write')">nul 2>&1 && echo %1 not locked || (
echo %1 Locked
("%systemroot%\system32\timeout.exe" /t 3)>nul
goto :loop
)
Note, the conditional operators (and &&
) and (or ||
) helps to evaluate the exit code without needing to do if
and else
statements.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |