Page 1 of 1

Capture return code of command executed by FORFILES

Posted: 24 Aug 2012 06:36
by WimSKW
Hi,

I'm using FORFILES to loop over a directory and move the containing files to a subdirectory based on a part of the filename.
The FORFILES line is as follows:

Code: Select all

FORFILES /M %strFileFilter% /D %strDateFilter% /c "cmd /c call \"%~f0\" :DoTheWork @ISDIR \"@PATH\" %iFrom% %iLen%"

The command that is executed by FORFILES is a subroutine in the same script so I restart the script with parameters. At the beginning of the script I check the parameters and CALL the label (:DoTheWork in this case).
The :DoTheWork routine checks whether it is a directory and if it's not, processes the file. It extracts the date part of the filename using the iFrom and iLen parameter, creates the subdirectory if needed and then moves the file. It returns with ENDLOCAL & (EXIT /B %ExitCode%).
After returning I check %ERRORLEVEL% in the line following FORFILES, but the returned errorlevel is from FORFILES and not from :DoTheWork.
When I use

Code: Select all

  FORFILES /M %strFileFilter% /D %strDateFilter% /c "cmd /c call \"%~f0\" :DoTheWork @ISDIR \"@PATH\" %iFrom% %iLen% && ECHO.OK || ECHO.NOK "

it nicely echoes OK or NOK depending on the ExitCode I set in :DoTheWork, but when I use

Code: Select all

  FORFILES /M %strFileFilter% /D %strDateFilter% /c "cmd /c call \"%~f0\" :DoTheWork @ISDIR \"@PATH\" %iFrom% %iLen% && SET ExitCode=0 || SET ExitCode=1 "

and check for %ExitCode% in the next line, ExitCode is empty i.e. the variable does not exist.

So is there a way to retrieve the return code of the command that is executed by FORFILES?

Thanks.
-=Wim=-

Re: Capture return code of command executed by FORFILES

Posted: 24 Aug 2012 06:42
by foxidrive
Get forfiles to create a file with the errorlevel and read that in your batch file.

The issue is that forfiles launches another CMD shell and the environment is lost when it closes.

Re: Capture return code of command executed by FORFILES

Posted: 24 Aug 2012 09:54
by WimSKW
Thanks for your quick answer.

I tried what you suggested:

Code: Select all

FORFILES /M %strFileFilter% /D %strDateFilter% /c "cmd /c call \"%~f0\" :DoTheWork @ISDIR \"@PATH\" %iFrom% %iLen% && ECHO.0>%temp%\res.txt || ECHO.1>%temp%\res.txt "
SET /p ExitCode=<%temp%\res.txt
and indeed ExitCode gets a value (funny enough the value has a trailing space when read from the file and I have no idea where that comes from).

The problem however is that it only gets the value of the last processed file, so if the last file gets successfully moved, ExitCode equals 0 even though :DoTheWork could not move some previous files.

I worked around this by looping to the FORFILES instruction again.
If there are new files in the folder, they will get moved and ExitCode will be 0, so loop again.
If the only files left are unmoveable, ExitCode will be 1, so it's done
If every file was moved, FORFILES exits with ERRORLEVEL 1 i.e. "ERROR: Files of type (...) not found", so it's also done.

Thanks for the tip.
-=Wim=-

Re: Capture return code of command executed by FORFILES

Posted: 24 Aug 2012 18:31
by foxidrive
WimSKW wrote:

Code: Select all

FORFILES /M %strFileFilter% /D %strDateFilter% /c "cmd /c call \"%~f0\" :DoTheWork @ISDIR \"@PATH\" %iFrom% %iLen% && ECHO.0>%temp%\res.txt || ECHO.1>%temp%\res.txt "
SET /p ExitCode=<%temp%\res.txt


You cannot redirect numbers like that into a file in NT.

You will need this kind of redirection:

Code: Select all

>%temp%\res.txt ECHO.0


But it seems you have a solution so I'll leave it there.