1

My problem is that two FOR loops are working separately, but don't want to work one after another.

The goal is:

The first loop creates XML files and only when the creation has already been done the second loop starts and counts the size of created XML files and writes it into .txt file.

@echo off
Setlocal EnableDelayedExpansion

for /f %%a in ('dir /b /s C:\Users\NekhayenkoO\test\') do (
    echo Verarbeite %%~na
    jhove -m PDF-hul -h xml -o C:\Users\NekhayenkoO\outputxml\%%~na.xml %%a
)

for /f %%i in ('dir /b /s C:\Users\NekhayenkoO\outputxml\') do (
    echo %%~ni %%~zi >> C:\Users\NekhayenkoO\outputxml\size.txt
)

pause
Mofi
  • 46,139
  • 17
  • 80
  • 143
Oleg_08
  • 447
  • 1
  • 4
  • 23

2 Answers2

1

This question can be answered easily when knowing what jhove is.

So I searched in world wide web for jhove, found very quickly the homepage JHOVE | JSTOR/Harvard Object Validation Environment and downloaded also jhove-1_11.zip from SourceForge project page of JHOVE.

All this was done by me to find out that jhove is a Java application which is executed on Linux and perhaps also on Mac using the shell script jhove and on Windows the batch file jhove.bat for making it easier to use by users.

So Windows command interpreter searches in current directory and next in all directories specified in environment variable PATH for a file matching the file name pattern jhove.* having a file extension listed in environment variable PATHEXT because jhove.bat is specified without file extension and without path in the batch file.

But the execution of a batch file from within a batch file without usage of command CALL results in script execution of current batch file being continued in the other executed batch file without ever returning back to the current batch file.

For that reason Windows command interpreter runs into jhove.bat on first file found in directory C:\Users\NekhayenkoO\test and never comes back.

This behavior can be easily watched by using two simple batch files stored for example in C:\Temp.

Test1.bat:

@echo off
cd /D "%~dp0"
for %%I in (*.bat) do Test2.bat "%%I"
echo %~n0: Leaving %~f0

Test2.bat:

@echo %~n0: Arguments are: %*
@echo %~n0: Leaving %~f0

On running from within a command prompt window C:\Temp\Test1.bat the output is:

Test2: Arguments are: "Test1.bat"
Test2: Leaving C:\Temp\Test2.bat

The processing of Test1.bat was continued on Test2.bat without coming back to Test1.bat.

Now Test1.bat is modified to by inserting command CALL after do.

Test1.bat:

@echo off
cd /D "%~dp0"
for %%I in (*.bat) do call Test2.bat "%%I"
echo Leaving %~f0

The output on running Test1.bat from within command prompt window is now:

Test2: Arguments are: "Test1.bat"
Test2: Leaving C:\Temp\Test2.bat
Test2: Arguments are: "Test2.bat"
Test2: Leaving C:\Temp\Test2.bat
Test1: Leaving C:\Temp\Test1.bat

Batch file Test1.bat calls now batch file Test2.bat and therefore the FOR loop is really executed on all *.bat files found in directory of the two batch files.

Therefore the solution is using command CALL as suggested already by Squashman:

@echo off
setlocal EnableDelayedExpansion

for /f %%a in ('dir /b /s "%USERPROFILE%\test\" 2^>nul') do (
    echo Verarbeite %%~na
    call jhove.bat -m PDF-hul -h xml -o "%USERPROFILE%\outputxml\%%~na.xml" "%%a"
)

for /f %%i in ('dir /b /s "%USERPROFILE%\outputxml\" 2^>nul') do (
    echo %%~ni %%~zi>>"%USERPROFILE%\outputxml\size.txt"
)

pause
endlocal

A reference to environment variable USERPROFILE is used instead of C:\Users\NekhayenkoO.

All file names are enclosed in double quotes in case of any file found in the directory contains a space character or any other special character which requires enclosing in double quotes.

And last 2>nul is added which redirects the error message output to handle STDERR by command DIR on not finding any file to device NUL to suppress it. The redirection operator > must be escaped here with ^ to be interpreted on execution of command DIR and not as wrong placed redirection operator on parsing already the command FOR.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • call /?
  • cd /?
  • dir /?
  • echo /?
  • for /?

And read also the Microsoft article Using command redirection operators.

Community
  • 1
  • 1
Mofi
  • 46,139
  • 17
  • 80
  • 143
0

You need to use the START command with the /WAIT flag when you launch an external application. I believe it would look something like this:

START /WAIT jhove -m PDF-hul -h xml -o C:\Users\NekhayenkoO\outputxml\%%~na.xml %%a

That should cause the batch file to pause and wait for the external application to finish before proceeding.

Bradley Uffner
  • 16,641
  • 3
  • 39
  • 76
  • it doesn't work. the external application can't be finished. it processes one pdf file already for 10 minutes – Oleg_08 Oct 21 '16 at 16:15
  • I'm not familiar with how jhove works, but if its process never actually exits, the batch file won't move beyond the `START` line. The only other solution that I can think of would be to insert a sufficiently large pause, such as `TIMEOUT 10` to wait for 10 seconds, but that may be unreliable or flaky in other ways. – Bradley Uffner Oct 21 '16 at 16:20
  • Some programs do not respect the /WAIT option. CALL has always solved that issue for me. – Squashman Oct 21 '16 at 16:46
  • Nice. I wasn't aware that `CALL` could be used on external applications, I thought it only worked on built-in commands and subroutines. You should add `CALL` as an answer. – Bradley Uffner Oct 21 '16 at 16:48