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