Skip to content
⌘ NSIS Forum Archive

IsEmptyDir check

7 posts

PoRtAbLe_StEaLtH#

IsEmptyDir check

Im not an expert .. but find NSIS an intriguing language.
I love the simplicity, and small overhead.

I discover new things everyday.

For instance.. today.. i learned:
IfFileExists 
if used with a wildcard to detect if files exists, will always return true, due to ".", "..".

Example:
IfFileExists `$INSTDIR\Dir\*.*` 0 skip
     MessageBox MB_OK "Did not skip."
skip: 
Using Logic:
${If} ${FileExists} `$INSTDIR\Dir\*.*`
     MessageBox MB_OK "Did not skip."
${EndIf} 
Both examples will execute MessageBox, because it will detect ".", "..".

I have put together a useful script that will allow both above examples to work.

;!include logiclib.nsh
!define IsEmptyDir `"" LL_IsEmptyDir`
!macro _LL_IsEmptyDir _a _b _t _f
    !insertmacro _LOGICLIB_TEMP
    ${EmptyDir} `${_b}` $_LOGICLIB_TEMP
    !insertmacro _= $_LOGICLIB_TEMP 1 `${_t}` `${_f}`
!macroend
!macro EmptyDir _DIR _VAR
    Push ${_DIR}
    Call EmptyDir
    Pop ${_VAR}
!macroend
!define EmptyDir `!insertmacro EmptyDir`
Function EmptyDir
; renamed isempty from:
; http://nsis.sourceforge.net/Check_if_dir_is_empty
  # Stack ->                    # Stack: <directory>
  Exch $0                       # Stack: $0
  Push $1                       # Stack: $1, $0
  FindFirst $0 $1 "$0\*.*"
  strcmp $1 "." 0 _notempty
    FindNext $0 $1
    strcmp $1 ".." 0 _notempty
      ClearErrors
      FindNext $0 $1
      IfErrors 0 _notempty
        FindClose $0
        Pop $1                  # Stack: $0
        StrCpy $0 1
        Exch $0                 # Stack: 1 (true)
        goto _end
     _notempty:
       FindClose $0
       ClearErrors
       Pop $1                   # Stack: $0
       StrCpy $0 0
       Exch $0                  # Stack: 0 (false)
  _end:
FunctionEnd 

Now you can do this:
${IfNot} ${IsEmptyDir} `$INSTDIR\Dir`
     MessageBox MB_OK "Did not skip."
${EndIf} 

im sure the script can be shortened/improved..
But im not an expert..
infact.. i would truly love it if someone could improve the "isEmptyDir" script w/ Logic.
gfm688#
System::Call Shlwapi::PathIsDirectoryEmpty(t"$INSTDIR\Dir")i.r0
StrCmp $0 1 0 +2
MessageBox MB_OK "Directory is empty"
PoRtAbLe_StEaLtH#edited
Amazing

Originally Posted by gfm688 View Post
System::Call Shlwapi::PathIsDirectoryEmpty(t"$INSTDIR\Dir")i.r0
StrCmp $0 1 0 +2
MessageBox MB_OK "Directory is empty"

Amazing. 👍

all of that code can now be shrunken to this:
!define IsEmptyDir `"" LL_IsEmptyDir`
!macro _LL_IsEmptyDir _a _b _t _f
    !insertmacro _LOGICLIB_TEMP
         System::Call Shlwapi::PathIsDirectoryEmpty(t"${_b}")i.r0 $_LOGICLIB_TEMP
    !insertmacro _= $_LOGICLIB_TEMP 1 `${_t}` `${_f}`
!macroend 
to call:
;!include LogicLib.nsh
${IfNot} ${IsEmptyDir} `$Dir_to_check`
     "code to execute"
${EndIf} 

Thank you gfm688.
gfm688#
!define IsEmptyDir `"" LL_IsEmptyDir`
!macro _LL_IsEmptyDir _a _b _t _f
!insertmacro _LOGICLIB_TEMP
System::Call `Shlwapi::PathIsDirectoryEmpty(t"${_b}")i.s`
Pop $_LOGICLIB_TEMP
!insertmacro _= $_LOGICLIB_TEMP 1 `${_t}` `${_f}`
!macroend
PoRtAbLe_StEaLtH#
Originally Posted by gfm688 View Post
!define IsEmptyDir `"" LL_IsEmptyDir`
!macro _LL_IsEmptyDir _a _b _t _f
!insertmacro _LOGICLIB_TEMP
System::Call `Shlwapi::PathIsDirectoryEmpty(t"${_b}")i.s`
Pop $_LOGICLIB_TEMP
!insertmacro _= $_LOGICLIB_TEMP 1 `${_t}` `${_f}`
!macroend
how come it works for me without popping?
Anders#
Originally Posted by gfm688 View Post
!define IsEmptyDir `"" LL_IsEmptyDir`
!macro _LL_IsEmptyDir _a _b _t _f
!insertmacro _LOGICLIB_TEMP
System::Call `Shlwapi::PathIsDirectoryEmpty(t"${_b}")i.s`
Pop $_LOGICLIB_TEMP
!insertmacro _= $_LOGICLIB_TEMP 1 `${_t}` `${_f}`
!macroend
You should change this code so it compares <> 0, BOOL can be > 1, it usually means success is non-zero...
PoRtAbLe_StEaLtH#
Thank you

Originally Posted by Anders View Post
You should change this code so it compares <> 0, BOOL can be > 1, it usually means success is non-zero...
How's this?

!define IsEmptyDir `"" LL_IsEmptyDir`
    !macro _LL_IsEmptyDir _a _b _t _f
    !insertmacro _LOGICLIB_TEMP
         System::Call `Shlwapi::PathIsDirectoryEmpty(t"${_b}")i.s`
    Pop $_LOGICLIB_TEMP
    !insertmacro _<> $_LOGICLIB_TEMP 0 `${_t}` `${_f}`
!macroend 

any recommendations for checking stack in a function/macro?