Recursively remove empty parent directories: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
No edit summary
 
(9 intermediate revisions by 3 users not shown)
Line 1: Line 1:
((PageAuthor|ParallaxTZ))
{{PageAuthor|ParallaxTZ}}


== Description ==
== Description ==
Line 5: Line 5:
This function and example function call can be used to recursively delete empty parent folders of a given folder.  
This function and example function call can be used to recursively delete empty parent folders of a given folder.  


(Courtesy of the folks at www.redbugtech.com)
(Courtesy of the folks at [http://www.redbugtech.com Redbug Technologies] (www.redbugtech.com))


== The Script ==
== The Script ==
Line 34: Line 34:


== Usage ==
== Usage ==
 
The function declaration (as above) must appear before the call in the installation script.
<highlight-nsis>
<highlight-nsis>
RMDir /r "$INSTDIR"    ;remove $INSTDIR and all files/subfolders
RMDir /r "$INSTDIR"    ;remove $INSTDIR and all files/subfolders
${RMDirUP} "$INSTDIR"  ;remove $INSTDIR's parents (if each is empty ONLY)
${RMDirUP} "$INSTDIR"  ;remove $INSTDIR's parents (if each is empty ONLY)
</highlight-nsis>
</highlight-nsis>
== Another function (by jiake) ==
<highlight-nsis>
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
</highlight-nsis>
== Known issues ==
If a directory include more than one empty sub directories, this function fails.


[[Category:Disk, Path & File Functions]]
[[Category:Disk, Path & File Functions]]

Latest revision as of 01:17, 5 December 2013

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.