Recursively remove empty parent directories: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
(Recurisvely Remove Empty Parent Folders)
 
 
(10 intermediate revisions by 4 users not shown)
Line 1: Line 1:
{{PageAuthor|ParallaxTZ}}
== Description ==
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 ==
 
<highlight-nsis>
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
</highlight-nsis>
 
== Usage ==
The function declaration (as above) must appear before the call in the installation script.
<highlight-nsis>
RMDir /r "$INSTDIR"    ;remove $INSTDIR and all files/subfolders
${RMDirUP} "$INSTDIR"  ;remove $INSTDIR's parents (if each is empty ONLY)
</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.


[[{{ns:14}}:Functions & Macros]]
[[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.