Recursively remove empty parent directories

From NSIS Wiki

Author: ParallaxTZ (talk, contrib)


Description

This function and example function call can be used to recursively delete empty parent folders of a given folder.

(Courtesy of the folks at Redbug Technologies (www.redbugtech.com))

The Script

Function un.RMDirUP
         !define RMDirUP '!insertmacro RMDirUPCall'
 
         !macro RMDirUPCall _PATH
                push '${_PATH}'
                Call un.RMDirUP
         !macroend
 
         ; $0 - current folder
         ClearErrors
 
         Exch $0
         ;DetailPrint "ASDF - $0\.."
         RMDir "$0\.."
 
         IfErrors Skip
         ${RMDirUP} "$0\.."
         Skip:
 
         Pop $0
FunctionEnd

Usage

The function declaration (as above) must appear before the call in the installation script.

RMDir /r "$INSTDIR"     ;remove $INSTDIR and all files/subfolders
${RMDirUP} "$INSTDIR"   ;remove $INSTDIR's parents (if each is empty ONLY)

Another function (by jiake)

Function RecursiveRemoveEmptyDirectory
	Exch $R0
	Push $R1
	Push $R2
lbl_loop:
	# Strip the last backslash
	StrCpy $R1 $R0 "" -1
	StrCmp $R1 "\" 0 +2
	StrCpy $R0 $R0 -1
	# Check if it is root path
	StrCpy $R1 $R0 2
	StrCmp $R1 $R0 lbl_end
	# Check if it is empty
	FindFirst $R1 $R2 "$R0\*.*"
lbl_dir:
	StrCmp $R2 "." +2
	StrCmp $R2 ".." 0 +3
	FindNext $R1 $R2
	Goto lbl_dir
	FindClose $R1
	# After skipping "." & ".."
	StrCmp $R2 "" 0 lbl_end
	# No more files found, it is an empty folder
	RMDir $R0
	# Get the parent folder and then loop
	GetFullPathName $R0 "$R0\.."
	Goto lbl_loop
lbl_end:
	Pop $R2
	Pop $R1
	Pop $R0
FunctionEnd
 
/*
# Calling Windows API version
Function RecursiveRemoveEmptyDirectory
	Exch $R0
	Push $R1
lbl_loop:
	System::Call "shlwapi::PathAddBackslash(tR0R0)"
	System::Call "shlwapi::PathIsRoot(tR0)i.R1"
	StrCmp $R1 0 0 lbl_end
	System::Call "shlwapi::PathIsDirectoryEmpty(tR0)i.R1"
	StrCmp $R1 0 lbl_end
	RMDir $R0
	System::Call "shlwapi::PathAppend(tR0R0,ts)" ".."
	Goto lbl_loop
lbl_end:
	Pop $R1
	Pop $R0
FunctionEnd
*/
 
Section -Test
	# Create a temp direcotry
	CreateDirectory "$TEMP\1\22\333\4444\55555"
	# Remove empty directories recursively
	Push "$TEMP\1\22\333\4444\55555"
	Call RecursiveRemoveEmptyDirectory
SectionEnd

Known issues

If a directory include more than one empty sub directories, this function fails.

Personal tools
donate