The question is of importance, since "The process cannot access the file because it is being used by another process." denotes that data integrity was lost.
Most likely the cause are glitches within the CMD script itself. Keep in mind that in terms of CMD any (...)
is not a means to lexically structure the script, but implicetely calls an additional CMD-instance! The same applies for call :Label ... goto :EOF
subroutines. This is to be undestood as: concurrent processes are launched. At least on a multicore machine, it also means, that those CMD-instances are not executed exactly aligned in the sequential order of the controlling batch script. In particular this concerns their output to the file system. Even if the batch script processor waits for the return of an additional CMD-instance, apparantly it doesn't know, when output to a file is written effectively and the respective file being released. Possibly the batch script processor keeps the file open on intention to speed up consecutive append operations, but fails to always guess appropriately which CMD-instance would become the next writer. A mechanism to explictely flush the write buffer and release the file isn't given.
- "The process cannot access ..." warnings most likely refer to write operations, only. Any test for accessibilty by utilizing a read operation won't help.
- As the warnings denote that the file of concern is written incompletely AND the written lines are not in the intended order, the answer to the original question is:
To retroactively find out which file was locked, each write-operation must be logged proactively with hints which file was intended to write to AND written lines should be tagged with some index that hints the intended writing order. By something like
set bFile=locktest.B.txt
del /Q %bFile%
for /L %%i in (0,1,%cBMax%) do @(
echo { %tFile%
echo echo !TIME! B_%%i
echo !TIME! B_%%i 1>>%tFile%
echo } %tFile%
)>>%bFile% 2>&1
and you get it [if you ask for DRY, compare "pipelining" below].
Unfortunately the file of concern could be the logfile, that would suffer incompleteness regarding the very point we are interested in. Whereas we rely on the logfile, as we are confronted with a non-deterministic runtime problem that we cannot terminatorily investigate in the console. Thus, we can conlude that the real questions are:
We could pipeline through a filter that searches for the warning by text processing. Don't do more than:
@ 2>&1 (...)|for /F "tokens=1*" %%t in ('more') do @if "%%t"=="The" echo !TIME! %%t %%u
It shows that pipelining breaks the delayed variable expansion, thus we can't do more with it than to transform the warning, that we want to catch, into a fatal (breaking) error by something like goto :EOF
, or to parrot the warning itself. Nevertheless, at this point you might be sure that you try to write to %tFile%, that you know without any need for delayed variable expansions from the environment. Thus, without the loss of data integrity in mind, an answer to the original question is:
@ 2>&1 (...)|for /F "tokens=1" %%t in ('more') do @if "%%t"=="The" echo %~n0[B]: cannot append to %tFile%