Locate
From NSIS Wiki
Jump to navigationJump to search
Author: Instructor (talk, contrib) |
Function "Locate" was superseded by the Locate plugin.
Page for NSIS 2.07 and below users
You can use the latest version of headers (recommended) or the following function code (put the function code in your script before calling it)
Function Description
____________________________________________________________________________ Locate v1.7 ____________________________________________________________________________ Find files, directories and empty directories with mask and size options. Syntax: ${Locate} "[Path]" "[Options]" "Function" "[Path]" ; Disk or Directory ; "[Options]" ; /L=[FD|F|D|DE|FDE] ; /L=FD - Locate Files and Directories (default) ; /L=F - Locate Files only ; /L=D - Locate Directories only ; /L=DE - Locate Empty Directories only ; /L=FDE - Locate Files and Empty Directories ; /M=[mask] ; /M=*.* - Locate all (default) ; /M=*.doc - Locate Work.doc, 1.doc ... ; /M=Pho* - Locate PHOTOS, phone.txt ... ; /M=win???.exe - Locate winamp.exe, winver.exe ... ; /M=winamp.exe - Locate winamp.exe only ; /S=No:No[B|K|M|G] ; /S= - Don't locate file size (faster) (default) ; /S=0:0B - Locate only files of 0 Bytes exactly ; /S=5:9K - Locate only files of 5 to 9 Kilobytes ; /S=:10M - Locate only files of 10 Megabyte or less ; /S=1G - Locate only files of 1 Gigabyte or more ; /G=[1|0] ; /G=1 - Locate with subdirectories (default) ; /G=0 - Locate without subdirectories ; /B=[0|1] ; /B=0 - Banner isn't used (default) ; /B=1 - Banner is used. Callback when function ; start to search in new directory "Function" ; Callback function when found Function "Function" ; $R9 "path\name" ; $R8 "path" ; $R7 "name" ; $R6 "size" ($R6="" if directory, $R6="0" if file with /S=) ; $R0-$R5 are not used (save data in them). ; ... Push $var ; If $var="StopLocate" Then exit from function ; ; !!!Important!!!: ; Always push something to stack ; (even if you do not intend to stop locate) ; otherwise unexpected thing will happen! FunctionEnd Note: -Error flag if disk or directory isn't exist -Error flag if syntax error
Example (Find one file):
Section ${Locate} "C:\ftp" "/L=F /M=RPC DCOM.rar /S=1K" "Example1" ; 'RPC DCOM.rar' file in 'C:\ftp' with size 1 Kb or more IfErrors 0 +2 MessageBox MB_OK "Error" IDOK +2 MessageBox MB_OK "$$R0=$R0" SectionEnd Function Example1 StrCpy $R0 $R9 ; $R0="C:\ftp\files\RPC DCOM.rar" MessageBox MB_YESNO '$R0$\n$\nFind next?' IDYES +2 StrCpy $0 StopLocate Push $0 FunctionEnd
Example (Write founded in text file):
Section GetTempFileName $R0 FileOpen $R1 $R0 w ${Locate} "C:\ftp" "/S=:2M /G=0" "Example2" ; folders and all files with size 2 Mb or less ; don't scan subdirectories FileClose $R1 IfErrors 0 +2 MessageBox MB_OK "Error" IDOK +2 Exec '"notepad.exe" "$R0"' SectionEnd Function Example2 StrCmp $R6 '' 0 +3 FileWrite $R1 "Directory=$R9$\r$\n" goto +2 FileWrite $R1 "File=$R9 Size=$R6 Mb$\r$\n" Push $0 FunctionEnd
Example (Write founded in INI file):
Section GetTempFileName $R0 ${Locate} "C:\ftp" "/L=F /S=0K" "Example3" ; all files in 'C:\ftp' with size detect in Kb IfErrors 0 +2 MessageBox MB_OK "Error" IDOK +2 Exec '"notepad.exe" "$R0"' SectionEnd Function Example3 WriteINIStr $R0 "$R8" "$R7" "$R6 Kb" Push $0 FunctionEnd
Example (Delete empty directories):
Section StrCpy $R2 0 StrCpy $R3 0 loop: StrCpy $R1 0 ${Locate} "C:\ftp" "/L=DE" "Example4" IntOp $R3 $R3 + 1 IntOp $R2 $R2 + $R1 StrCmp $R0 StopLocate +2 StrCmp $R1 0 0 loop IfErrors 0 +2 MessageBox MB_OK 'error' IDOK +2 MessageBox MB_OK '$R2 directories were removed$\n$R3 loops' SectionEnd Function Example4 MessageBox MB_YESNOCANCEL 'Delete empty "$R9"?' IDNO end IDCANCEL cancel RMDir $R9 IntOp $R1 $R1 + 1 goto end cancel: StrCpy $R0 StopLocate end: Push $R0 FunctionEnd
Example (Move all files into one folder):
Section StrCpy $R0 "C:\ftp" ;Directory move from StrCpy $R1 "C:\ftp2" ;Directory move into StrCpy $R2 0 StrCpy $R3 0 ${Locate} "$R0" "/L=F" "Example5" IfErrors 0 +2 MessageBox MB_OK 'error' IDOK +4 StrCmp $R3 0 0 +2 MessageBox MB_OK '$R2 files were moved' IDOK +2 MessageBox MB_OK '$R2 files were moved$\n$R3 files were NOT moved' SectionEnd Function Example5 StrCmp $R8 $R1 +6 IfFileExists '$R1\$R7' +4 Rename $R9 '$R1\$R7' IntOp $R2 $R2 + 1 goto +2 IntOp $R3 $R3 + 1 Push $0 FunctionEnd
Example (Copy files with log):
Section StrCpy $R0 "C:\ftp" ;Directory copy from StrCpy $R1 "C:\ftp2" ;Directory copy into StrLen $R2 $R0 GetTempFileName $0 FileOpen $R3 $0 w ${Locate} "$R0" "/L=FDE" "Example6" FileClose $R3 IfErrors 0 +2 MessageBox MB_OK 'error' Exec '"notepad.exe" "$0"' ;view log SectionEnd Function Example6 StrCpy $1 $R8 '' $R2 StrCmp $R6 '' 0 +3 CreateDirectory '$R1$1\$R7' goto end CreateDirectory '$R1$1' CopyFiles /SILENT $R9 '$R1$1' IfFileExists '$R1$1\$R7' 0 +3 FileWrite $R3 "-old:$R9 -new:$R1$1\$R7 -success$\r$\n" goto +2 FileWrite $R3 "-old:$R9 -new:$R1$1\$R7 -failed$\r$\n" end: Push $0 FunctionEnd
Example (Recreate directory structure):
Section StrCpy $R0 "C:\ftp" ;Directory structure from StrCpy $R1 "C:\ftp2" ;Directory structure into StrLen $R2 $R0 ${Locate} "$R0" "/L=D" "Example7" IfErrors 0 +2 MessageBox MB_OK 'error' SectionEnd Function Example7 StrCpy $1 $R9 '' $R2 CreateDirectory '$R1$1' Push $0 FunctionEnd
Example (Locate with banner − nxs plugin required):
Section nxs::Show /NOUNLOAD `$(^Name) Setup` /top `Setup searching something$\r$\nPlease wait... If you can..` /h 1 /can 1 /end ${Locate} "C:\WINDOWS" "/L=F /M=*.inf /B=1" "Example8" nxs::Destroy SectionEnd Function Example8 StrCmp $R0 $R8 abortcheck StrCpy $R0 $R8 nxs::Update /NOUNLOAD /sub "$R8" /pos 78 /end abortcheck: nxs::HasUserAborted /NOUNLOAD Pop $0 StrCmp $0 1 0 +2 StrCpy $0 StopLocate StrCmp $R9 '' end ;... end: Push $0 FunctionEnd
Function Code
Function Locate !define Locate `!insertmacro LocateCall` !macro LocateCall _PATH _OPTIONS _FUNC Push $0 Push `${_PATH}` Push `${_OPTIONS}` GetFunctionAddress $0 `${_FUNC}` Push `$0` Call Locate Pop $0 !macroend Exch $2 Exch Exch $1 Exch Exch 2 Exch $0 Exch 2 Push $3 Push $4 Push $5 Push $6 Push $7 Push $8 Push $9 Push $R6 Push $R7 Push $R8 Push $R9 ClearErrors StrCpy $3 '' StrCpy $4 '' StrCpy $5 '' StrCpy $6 '' StrCpy $7 '' StrCpy $8 0 StrCpy $R7 '' StrCpy $R9 $0 1 -1 StrCmp $R9 '\' 0 +3 StrCpy $0 $0 -1 goto -3 IfFileExists '$0\*.*' 0 error option: StrCpy $R9 $1 1 StrCpy $1 $1 '' 1 StrCmp $R9 ' ' -2 StrCmp $R9 '' sizeset StrCmp $R9 '/' 0 -4 StrCpy $9 -1 IntOp $9 $9 + 1 StrCpy $R9 $1 1 $9 StrCmp $R9 '' +2 StrCmp $R9 '/' 0 -3 StrCpy $R8 $1 $9 StrCpy $R8 $R8 '' 2 StrCpy $R9 $R8 '' -1 StrCmp $R9 ' ' 0 +3 StrCpy $R8 $R8 -1 goto -3 StrCpy $R9 $1 2 StrCpy $1 $1 '' $9 StrCmp $R9 'L=' 0 mask StrCpy $3 $R8 StrCmp $3 '' +6 StrCmp $3 'FD' +5 StrCmp $3 'F' +4 StrCmp $3 'D' +3 StrCmp $3 'DE' +2 StrCmp $3 'FDE' 0 error goto option mask: StrCmp $R9 'M=' 0 size StrCpy $4 $R8 goto option size: StrCmp $R9 'S=' 0 gotosubdir StrCpy $6 $R8 goto option gotosubdir: StrCmp $R9 'G=' 0 banner StrCpy $7 $R8 StrCmp $7 '' +3 StrCmp $7 '1' +2 StrCmp $7 '0' 0 error goto option banner: StrCmp $R9 'B=' 0 error StrCpy $R7 $R8 StrCmp $R7 '' +3 StrCmp $R7 '1' +2 StrCmp $R7 '0' 0 error goto option sizeset: StrCmp $6 '' default StrCpy $9 0 StrCpy $R9 $6 1 $9 StrCmp $R9 '' +4 StrCmp $R9 ':' +3 IntOp $9 $9 + 1 goto -4 StrCpy $5 $6 $9 IntOp $9 $9 + 1 StrCpy $1 $6 1 -1 StrCpy $6 $6 -1 $9 StrCmp $5 '' +2 IntOp $5 $5 + 0 StrCmp $6 '' +2 IntOp $6 $6 + 0 StrCmp $1 'B' 0 +3 StrCpy $1 1 goto default StrCmp $1 'K' 0 +3 StrCpy $1 1024 goto default StrCmp $1 'M' 0 +3 StrCpy $1 1048576 goto default StrCmp $1 'G' 0 error StrCpy $1 1073741824 default: StrCmp $3 '' 0 +2 StrCpy $3 'FD' StrCmp $4 '' 0 +2 StrCpy $4 '*.*' StrCmp $7 '' 0 +2 StrCpy $7 '1' StrCmp $R7 '' 0 +2 StrCpy $R7 '0' StrCpy $7 'G$7B$R7' StrCpy $8 1 Push $0 SetDetailsPrint textonly nextdir: IntOp $8 $8 - 1 Pop $R8 StrCpy $9 $7 2 2 StrCmp $9 'B0' +3 GetLabelAddress $9 findfirst goto call DetailPrint 'Search in: $R8' findfirst: FindFirst $0 $R7 '$R8\$4' IfErrors subdir StrCmp $R7 '.' 0 +5 FindNext $0 $R7 StrCmp $R7 '..' 0 +3 FindNext $0 $R7 IfErrors subdir dir: IfFileExists '$R8\$R7\*.*' 0 file StrCpy $R6 '' StrCmp $3 'DE' +4 StrCmp $3 'FDE' +3 StrCmp $3 'FD' precall StrCmp $3 'F' findnext precall FindFirst $9 $R9 '$R8\$R7\*.*' StrCmp $R9 '.' 0 +4 FindNext $9 $R9 StrCmp $R9 '..' 0 +2 FindNext $9 $R9 FindClose $9 IfErrors precall findnext file: StrCmp $3 'FDE' +3 StrCmp $3 'FD' +2 StrCmp $3 'F' 0 findnext StrCpy $R6 0 StrCmp $5$6 '' precall FileOpen $9 '$R8\$R7' r IfErrors +3 FileSeek $9 0 END $R6 FileClose $9 System::Int64Op $R6 / $1 Pop $R6 StrCmp $5 '' +2 IntCmp $R6 $5 0 findnext StrCmp $6 '' +2 IntCmp $R6 $6 0 0 findnext precall: StrCpy $9 0 StrCpy $R9 '$R8\$R7' call: Push $0 Push $1 Push $2 Push $3 Push $4 Push $5 Push $6 Push $7 Push $8 Push $9 Push $R7 Push $R8 StrCmp $9 0 +4 StrCpy $R6 '' StrCpy $R7 '' StrCpy $R9 '' Call $2 Pop $R9 Pop $R8 Pop $R7 Pop $9 Pop $8 Pop $7 Pop $6 Pop $5 Pop $4 Pop $3 Pop $2 Pop $1 Pop $0 IfErrors error StrCmp $R9 'StopLocate' clearstack goto $9 findnext: FindNext $0 $R7 IfErrors 0 dir FindClose $0 subdir: StrCpy $9 $7 2 StrCmp $9 'G0' end FindFirst $0 $R7 '$R8\*.*' StrCmp $R7 '.' 0 +5 FindNext $0 $R7 StrCmp $R7 '..' 0 +3 FindNext $0 $R7 IfErrors +7 IfFileExists '$R8\$R7\*.*' 0 +3 Push '$R8\$R7' IntOp $8 $8 + 1 FindNext $0 $R7 IfErrors 0 -4 FindClose $0 StrCmp $8 0 end nextdir error: SetErrors clearstack: StrCmp $8 0 end IntOp $8 $8 - 1 Pop $R8 goto clearstack end: SetDetailsPrint both Pop $R9 Pop $R8 Pop $R7 Pop $R6 Pop $9 Pop $8 Pop $7 Pop $6 Pop $5 Pop $4 Pop $3 Pop $2 Pop $1 Pop $0 FunctionEnd