开发者

How to make NSIS RMDir operate on subdirectories?

开发者 https://www.devze.com 2023-01-08 08:51 出处:网络
In an NSIS installer script I have: RMDir \"$INSTDIR\" Now, if the user sets the installation directory to C:\\Program Files\\Product, it works fine, however if they install to 开发者_StackOverflow

In an NSIS installer script I have:

RMDir "$INSTDIR"

Now, if the user sets the installation directory to C:\Program Files\Product, it works fine, however if they install to 开发者_StackOverflow中文版something deeper, such as C:\Program Files\Company\Product for example, RMDir gets rid of "Product" but not "Company". How can I make it delete each empty directory down to the root (WITHOUT using /r)... e.g. delete Product if empty, delete Company if empty, delete Program Files if empty, and so on?


EDIT: The function I ended up using:

# Delete empty directories recursively
var deleteDir
var dirLength
Function un.PathDeleteEmptyDirRecurse
ClearErrors
loop:
    Sleep 50 ; Without a small delay here, the directory sometimes won't get removed
    RMDir "$deleteDir" ; Remove the directory
    IfErrors end
    strlen $dirLength $deleteDir ; Store the length of the path
    intcmp $dirLength 3 end end ; If the length of the path is <= 3 (e.g. C:\), we're at the root drive
    GetFullPathName $deleteDir "$deleteDir\.." ; <path>\.. results in the parent directory of <path>
    IfErrors end loop
end:
FunctionEnd


I assume you want this in the uninstaller and not the installer:

Function un.PathDeleteEmptyDirRecurse 
exch $0
push $1
ClearErrors
loop:
RMDir $0
IfErrors end
strlen $1 $0
intcmp $1 3 end end ;root of drive?
GetFullPathName $0 "$0\.."
IfErrors end loop
end:
pop $1
pop $0
FunctionEnd

...

push $instdir
call un.PathDeleteEmptyDirRecurse


Here's what I use;

Function un.RMDirUP
  !define RMDirUP '!insertmacro RMDirUPCall'
  !macro RMDirUPCall _PATH
      push '${_PATH}'
      Call un.RMDirUP
  !macroend

  ; $0 - current folder
  ClearErrors
  Exch $0
  RMDir "$0\.."
  IfErrors Skip
  ${RMDirUP} "$0\.."
  Skip:
  Pop $0
FunctionEnd

This let's you call it in the uninstall with ${RMDirUP} "$INSTDIR"


I finally ended up using just these two lines to delete everything in the installation directory and the directory itself (if empty):

RMDir /r "$INSTDIR"
RMDir "$INSTDIR\..\."
0

精彩评论

暂无评论...
验证码 换一张
取 消