10

We have a batch script that removes files (del) and directories (rd). Does anyone know how to halt (fail) execution of the script if any of these delete statements fail? They could fail if a file/directory is locked by Windows. Thanks.

Update

Statements I'm using:

Del: del *.* /S /Q

RD: FOR /D %%G in (*) DO RD /s /q %%G

Simon Kissane
  • 4,373
  • 3
  • 34
  • 59
Marcus Leon
  • 55,199
  • 118
  • 297
  • 429

10 Answers10

13

For deleting the files, you can first try to ren (rename) the file. ren will set ERRORLEVEL to 1 if the file is locked. Add quotes around filename.

@echo OFF

:: Delete all files, but exit if a file is locked.
for %%F in (*.*) do (
    @echo Deleting %%F
    ren "%%F" tmp 2> nul
    if ERRORLEVEL 1 (
        @echo Cannot delete %%F, it is locked.
        exit /b 1
    )
    del tmp
)

I suspect you may be able to do the same thing for directories, but I can't seem to figure out how to get a directory locked so I can test. The following may work:

:: Remove all directories, but exit if one is locked.
FOR /D %%G in (*) DO (
    @echo Removing %%G
    ren "%%G" tmpdir 2> nul
    if ERRORLEVEL 1 (
        @echo Cannot remove %%G, it is locked
        exit /b 1
    )
    RD /s /q tmpdir
)
Community
  • 1
  • 1
Patrick Cuff
  • 28,540
  • 12
  • 67
  • 94
  • 1
    This is not working for running process image file. When you start `notepad.exe` you can successfully rename it, but you can't delete its image file. Same for loaded DLLs. – wqw May 11 '11 at 07:05
8

DEL doesn't return an errorlevel if the file is locked. I just did a test with excel file and I saw a zero (on Windows XP).

It might be better to use IF EXIST for the file to be deleted after you do the delete.

del file.txt
if exist file.txt ECHO "FAIL"

AFTER EDIT Disclaimer: I have no idea how this performs...

You could do this for the files

DIR /B /S /A-d > c:\filestodelete.txt

del *.* /S /Q    

FOR /F %%i in (c:\filestodelete.txt) DO (
    IF EXIST %%i ECHO %%i STILL EXISTS
)

then for the directories

DIR /B /S /Ad > c:\directoriestodelete.txt

FOR /D %%G in (*) DO RD /s /q %%G    

FOR /F %%i in (c:\directoriestodelete.txt) DO (
    IF EXIST %%i ECHO %%i STILL EXISTS
)
Restore the Data Dumps
  • 38,967
  • 12
  • 96
  • 122
  • Good suggestion - except I am removing multiple files (see edited post) so it's hard to do the exist statement for each dir/file. – Marcus Leon Feb 18 '09 at 13:23
3

EDIT: Right, so del does not set the ERRORLEVEL correctly. See ERRORLEVEL on DEL and Windows delete command can fail silently

PREVIOUS (incorrect) SOLUTION

You should check the errorlevel.

For example:

del file.txt
if errorlevel 1 goto FAIL
:PASS
echo Worked!
goto :END

:FAIL
echo Failed!
exit /B 1

:END
dbenham
  • 127,446
  • 28
  • 251
  • 390
grammar31
  • 2,000
  • 1
  • 12
  • 17
  • Doesn't seem to work: C:\>test.bat C:\>del boo.doc boo.doc. The process cannot access the file because it is being used by another process. C:\>if errorlevel 1 goto FAIL C:\>echo Worked! Worked! C:\>echo Failed! Failed! C:\>exit /B 1 – Marcus Leon Feb 18 '09 at 13:20
  • The URL to the docs no longer work. – Mat Lipe Sep 14 '22 at 18:23
1

Here's my preferred way to check for errors while deleting files. We redirect the "error output" (standard file "2") to a file (e.g. delCmd.err). Then we use the FOR command as a way to get access to the ~z "file size" operater. If the size of the output file is not 0, then we know that "del" got an error... we display the error with the "type" command and exit the batch file with a non-zero error code:

del unwanted.txt 2> delCmd.err
FOR /F "usebackq" %%A IN ('delCmd.err') DO set size=%%~zA
if not "%size%"=="0" (
    echo Error deleting unwanted.txt
    type delCmd.err
    exit /B 1
)
JoelFan
  • 37,465
  • 35
  • 132
  • 205
1

Just for your information. The DEL command does return an error code if a serious error occurs, however it's behavior is way beyond our intuition that people would simply believe that the error code doesn't work at all.

This is what I've tested in DEL command in Windows 7:

  • Successful deletion of all files: 0 (of course)
  • Some files deleted, some files missing: 0 (intuition expects 1)
  • Deletion failure due to no permission or a read-only medium: 0 (intuition expects ≥ 1)
  • Non-existent drive or drive not ready (such as no CD on a CD-ROM drive): 1 (yes, you get it, but I will expect a higher error code)
  • Invalid path: 1 (I will expect a higher error code, too)

And, if you specify a list of files to DEL command, where at least one of the files fit the last two kinds of error mentioned above, then none of the files in the list will be deleted at all.

Explorer09
  • 569
  • 5
  • 9
1

Here is a shorter version of the result monitoring variant. This is using 2>&1 trick to redirect stderr to stdout and for /f to check for any output.

@echo off
setlocal
set error=0
for /f %%i in ('del notepad2.exe 2^>^&1') do set error=1
echo %error%
wqw
  • 11,771
  • 1
  • 33
  • 41
0

There is a script that will work like a charm. It tests deletion failure by testing the existence of the supposedly deleted file/directory.

The output will be an existing c:\mydirectory with completely empty content. Any error breaks the process and is reported.

The only downside is that directories are removed recursively, because there is no simple way to start deleting directories starting with the most "sub" directories.

@echo OFF
set path_to_clean=c:\mydirectory

@echo -Deleting Files
dir /A-D /S /B %path_to_clean%\* > fileslist.txt
for /F %%F in (fileslist.txt) do (
    @echo Deleting %%F
    del %%F 2> nul
    if exist %%F (
        @echo Cannot delete %%F, it is locked.
        goto errorhandling
    )
)
del fileslist.txt
@echo -Deleting Files done

@echo -Deleting Directories
dir /AD /B %path_to_clean%\* > directorieslist.txt

for /F %%D in (directorieslist.txt) do (
    @echo Deleting %path_to_clean%\%%D
    rmdir /S /Q %path_to_clean%\%%D 2> nul
    if exist %path_to_clean%\%%D (
        @echo Cannot delete %path_to_clean%\%%D. This folder or one of its sub-directories is locked.
        goto errorhandling
    )
)
del directorieslist.txt
@echo -Deleting Directories done

:errorhandling
rem some code here
Gryzorz
  • 320
  • 2
  • 5
0

These seem to work for me:

RD:

FOR /D %d IN (*) DO ( RD /S /Q "%d" & IF EXIST "%d" EXIT /B 1 )

DEL:

FOR %f IN (*.*) DO ( DEL /Q "%f" & IF EXIST "%f" EXIT /B 1 )

No idea about the performance though.

You can add flag /F to DEL for a "force delete" mode.

jhyot
  • 3,733
  • 1
  • 27
  • 44
-1

For rd and rmdir you can do

rd "some directory" || rem

this will set the errorlevel correctly - see

Community
  • 1
  • 1
Tim
  • 1
-2

Hi This should work as well

@echo off  

for /f %%i in ('del notepad2.exe 2^>^&1') do set ERRORLEVEL=1
IF %ERRORLEVEL%=1 then exit
  • 3
    You should ***NEVER*** set the ERRORLEVEL variable directly. The user defined value will override the dynamic value. `%ERRORLEVEL%` will no longer report the returned error code of the previous command(s). Instead it will forever expand to the value you set. – dbenham Aug 06 '14 at 17:41