Search For a File: Difference between revisions
m (Updated author links.) |
m (<clean> instead of <clean>) |
||
(3 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
{ | {{PageAuthor|KiCHiK}} | ||
== Description == | == Description == | ||
This function searches a given directory and all of its subdirectories for a certain file (or directory). Whenever it finds a match it calls a given callback function. If the callback function returns "stop" the function will stop searching. | This function searches a given directory and all of its subdirectories for a certain file (or directory). Whenever it finds a match it calls a given callback function. If the callback function returns "stop" the function will stop searching. | ||
Line 12: | Line 10: | ||
'''Warning:''' do not push a directory with a trailing backslash. To remove the trailing backslash automatically use (assuming the input is in $0): | '''Warning:''' do not push a directory with a trailing backslash. To remove the trailing backslash automatically use (assuming the input is in $0): | ||
<highlight-nsis>Push $0 # directory | <highlight-nsis>Push $0 # directory to remove trailing backslash from. Stack: $0(with backslash) | ||
Exch $EXEDIR | Exch $EXEDIR # exchange with a built-in dir var - exedir will do. | ||
# NSIS automatically removes the trailing backslash. Stack: $EXEDIR(original) | |||
Exch $EXEDIR</highlight-nsis>Forum user [user:banaman8d banaman8d] have written a variant of this script that lets the callback function do the comparison. Click [http://forums.winamp.com/attachment.php?s=&postid=975844 here] to get it. | Exch $EXEDIR # restore original dir var. Stack: $0(without backslash) | ||
Pop $0 # and pop the directory without the backslash. Stack: <clean></highlight-nsis>Forum user [user:banaman8d banaman8d] have written a variant of this script that lets the callback function do the comparison. Click [http://forums.winamp.com/attachment.php?s=&postid=975844 here] to get it. | |||
A simple macro is included to simplify the process of getting your callback function's address. | A simple macro is included to simplify the process of getting your callback function's address. | ||
Line 199: | Line 198: | ||
SectionEnd | SectionEnd | ||
</highlight-nsis> | </highlight-nsis> | ||
[[Category:Disk, Path & File Functions]] |
Latest revision as of 12:22, 24 October 2005
Author: KiCHiK (talk, contrib) |
Description
This function searches a given directory and all of its subdirectories for a certain file (or directory). Whenever it finds a match it calls a given callback function. If the callback function returns "stop" the function will stop searching.
The function gets a directory to search, a file/directory name and an address to a callback function (use GetFunctionAddress) through the stack.
This function is based on a code originally written by Justin Frankel.
Warning: do not push a directory with a trailing backslash. To remove the trailing backslash automatically use (assuming the input is in $0):
Push $0 # directory to remove trailing backslash from. Stack: $0(with backslash) Exch $EXEDIR # exchange with a built-in dir var - exedir will do. # NSIS automatically removes the trailing backslash. Stack: $EXEDIR(original) Exch $EXEDIR # restore original dir var. Stack: $0(without backslash) Pop $0 # and pop the directory without the backslash. Stack: <clean>
Forum user [user:banaman8d banaman8d] have written a variant of this script that lets the callback function do the comparison. Click here to get it.
A simple macro is included to simplify the process of getting your callback function's address.
!macro CallFindFiles DIR FILE CBFUNC Push "${DIR}" Push "${FILE}" Push $0 GetFunctionAddress $0 "${CBFUNC}" Exch $0 Call FindFiles !macroend
Callback Function Syntax
- Do not use $R0-$R6 in the function unless you are saving their old content*Return a "stop" value if you want to stop searching, anything else to continue
- Always return a value through the stack (Push) to prevent stack corruption*Do not push values on the stack without poping them later unless it's the return value
Example of Callback Function
Function MyCallbackFunction Exch $0 DetailPrint $0 Pop $0 Push "stop" FunctionEnd
The Function Code
Function FindFiles Exch $R5 # callback function Exch Exch $R4 # file name Exch 2 Exch $R0 # directory Push $R1 Push $R2 Push $R3 Push $R6 Push $R0 # first dir to search StrCpy $R3 1 nextDir: Pop $R0 IntOp $R3 $R3 - 1 ClearErrors FindFirst $R1 $R2 "$R0\*.*" nextFile: StrCmp $R2 "." gotoNextFile StrCmp $R2 ".." gotoNextFile StrCmp $R2 $R4 0 isDir Push "$R0\$R2" Call $R5 Pop $R6 StrCmp $R6 "stop" 0 isDir loop: StrCmp $R3 0 done Pop $R0 IntOp $R3 $R3 - 1 Goto loop isDir: IfFileExists "$R0\$R2\*.*" 0 gotoNextFile IntOp $R3 $R3 + 1 Push "$R0\$R2" gotoNextFile: FindNext $R1 $R2 IfErrors 0 nextFile done: FindClose $R1 StrCmp $R3 0 0 nextDir Pop $R6 Pop $R3 Pop $R2 Pop $R1 Pop $R0 Pop $R5 Pop $R4 FunctionEnd
A Complete Example
This example will look for Winamp.exe versioned 2.9+ all over the C: drive.
Name "FindFiles example" OutFile FindFiles.exe ShowInstDetails show Function FindFiles Exch $R5 # callback function Exch Exch $R4 # file name Exch 2 Exch $R0 # directory Push $R1 Push $R2 Push $R3 Push $R6 Push $R0 # first dir to search StrCpy $R3 1 nextDir: Pop $R0 IntOp $R3 $R3 - 1 ClearErrors FindFirst $R1 $R2 "$R0\*.*" nextFile: StrCmp $R2 "." gotoNextFile StrCmp $R2 ".." gotoNextFile StrCmp $R2 $R4 0 isDir Push "$R0\$R2" Call $R5 Pop $R6 StrCmp $R6 "stop" 0 isDir loop: StrCmp $R3 0 done Pop $R0 IntOp $R3 $R3 - 1 Goto loop isDir: IfFileExists "$R0\$R2\*.*" 0 gotoNextFile IntOp $R3 $R3 + 1 Push "$R0\$R2" gotoNextFile: FindNext $R1 $R2 IfErrors 0 nextFile done: FindClose $R1 StrCmp $R3 0 0 nextDir Pop $R6 Pop $R3 Pop $R2 Pop $R1 Pop $R0 Pop $R5 Pop $R4 FunctionEnd !macro CallFindFiles DIR FILE CBFUNC Push "${DIR}" Push "${FILE}" Push $0 GetFunctionAddress $0 "${CBFUNC}" Exch $0 Call FindFiles !macroend Function FindWinamp29 Pop $0 GetDLLVersion $0 $1 $3 IntOp $2 $1 & 0x0000FFFF IntOp $1 $1 / 0x00010000 IntOp $4 $3 & 0x0000FFFF IntOp $3 $3 / 0x00010000 DetailPrint "$1.$2.$3.$4 - $0" StrCmp "$1.$2" "2.9" 0 not StrCpy $9 $0 DetailPrint "This is the one! Stopping search..." Push "stop" Return not: Push "go" FunctionEnd Section "Find Winamp" !insertmacro CallFindFiles C: winamp.exe FindWinamp29 StrCmp $9 "" 0 +2 DetailPrint "Couldn't find Winamp 2.9+" SectionEnd