- NSIS Discussion
- FindFirst
Archive: FindFirst
bnicer
8th March 2007 18:54 UTC
FindFirst
Hi
I recommend a small change in the FindFirst usage:
user_var(handle output) user_var(filename output) filespec
or
FindFirst $0 $1 $INSTDIR\*.txt
The documentation claims if no files are found, both outputs ($0 + $1) are set to empty and an error flag is set.
This is only 99% true. If the folder is empty and the file search has 2 wildcards:
FindFirst $0 $1 $INSTDIR\*.*
the first variable returns the search handle (some number), the second variable returns an empty string and no error flag is set.
To check if any files are in the folder, you need:
CmpStr $1 ""
IfErrors is unreliable.
I hope I'm not being petty.
Red Wine
8th March 2007 19:37 UTC
IfErrors is 100% reliable, using wildcards "*.*" returns the dots "." and ".." specifying the directory.
bnicer
8th March 2007 19:46 UTC
Oops. I didn't see the dot. The second variable returns a decimal point, dot.
I'm beginning to wonder if having two wildcard characters is such a good idea in the search string.
CmpStr $1 "." doesn't feel right.
May I give this over to the experts panel (no offense) to pore over?
Does FindFirst recognize $INSTDIR\*.* to mean any files or subfolders in $INSTDIR?
edit:
Red Wine, you beat me to it.
IfErrors is still inaccurate, since no error flag is set with an empty folder.
Red Wine
8th March 2007 20:05 UTC
Ok, 2 examples to help you a bit :)
outfile 'find.exe'
ShowInstDetails show
section -
SetOutPath "$EXEDIR"
CreateDirectory "$EXEDIR\boo"
FileOpen $R0 "$EXEDIR\boo\test1.txt" w
FileClose $R0
FileOpen $R0 "$EXEDIR\boo\test2.txt" w
FileClose $R0
ClearErrors
FindFirst $0 $1 "$EXEDIR\boo\*.*"
StrCmp $1 "." +2
StrCpy $2 "$1$\r$\n"
loop:
FindNext $0 $1
IfErrors end
StrCmp $1 ".." loop
StrCpy $2 "$2$1$\r$\n"
goto loop
end:
StrCmp $2 "" 0 +2
MessageBox MB_OK "Error! No Files found" IDOK +2
MessageBox MB_OK "Files found: $\r$\n$2"
FindClose $0
Delete "$EXEDIR\boo\test1.txt"
Delete "$EXEDIR\boo\test2.txt"
Rmdir "$EXEDIR\boo"
sectionend
outfile 'find.exe'
ShowInstDetails show
section -
SetOutPath "$EXEDIR"
CreateDirectory "$EXEDIR\boo"
ClearErrors
FindFirst $0 $1 "$EXEDIR\boo\*.*"
StrCmp $1 "." +2
StrCpy $2 "$1$\r$\n"
loop:
FindNext $0 $1
IfErrors end
StrCmp $1 ".." loop
StrCpy $2 "$2$1$\r$\n"
goto loop
end:
StrCmp $2 "" 0 +2
MessageBox MB_OK "Error! No Files found" IDOK +2
MessageBox MB_OK "Files found: $\r$\n$2"
FindClose $0
Rmdir "$EXEDIR\boo"
sectionend
bnicer
8th March 2007 23:49 UTC
I withdraw my usage proposal.
To find out if the folder is empty, FindNext should loop.
FindFirst $0 $1 $INSTDIR\*.* returns an error if the directory does not exist.
Thx!:)
I used the code below. (Took me a while to figure out though.)
FindFirst $0 $1 "$INSTDIR\*.*"
IfErrors skip
loop:
FindNext $0 $1
IfErrors skip
StrCmp $1 ".." loop
MessageBox MB_ICONSTOP|MB_OK "The folder is not empty."
FindClose $0
Abort
skip:
Red Wine
9th March 2007 00:08 UTC
If you want to check a directory, you may use DirState or Locate .
Brummelchen
9th March 2007 01:34 UTC
i worked with RecFind successfully last weeks
http://nsis.sourceforge.net/RecFind:...t%2C_FindClose
it is the more convenient way.
bnicer
9th March 2007 03:21 UTC
RecFind does a recursive search through the whole directory tree, which is slightly more than I need at the moment. I don't know how to stop it from looping when the folder is not empty. It could explain that better in the examples, imo.
${DirState} "$INSTDIR" $R0
StrCmp $R0 "1" 0 skip
is simpler.
Thanks again.
edit:
A recursive file search tool is impressive.
Brummelchen
9th March 2007 22:25 UTC
>> A recursive file search tool is impressive.
Thats a bit tricky...
RecFind seems oversized but it is easy to handle...
it returns "" (emtpy) when he finds another subfolder
just skip to recfindnext
example
;find filemask
>${RecFindOpen} "$FOLDER" $0 $1
StrCmp$0 "" 0 findfile1_done1
>${RecFindFirst}
;your code
>;fetch next file
findfile1_next:
${RecFindNext}
;end file loop
findfile1_done1:
${RecFindClose}
i currently work with an array to grab all folders then fetch files.