» Locate: поиск файлов/папок и не только...

K.A.V.
www.oszone.net
22.02.2010
Автор: K.A.V.
Последнее обновление: 01.09.2011

Для выполнения команды необходимо:
!include "FileFunc.nsh"
${Locate}
Команда "Locate" позволяет найти файлы, директории и пустые папки с использованием маски и параметров размера.

${Locate} "[Путь]" "[Параметры]" "Функция"

"[Путь]"      ; Диск или директория
              ;
"[Параметры]" ; /L=[FD|F|D|DE|FDE]
              ;     /L=FD    - Поиск файлов и папок (по-умолчанию)
              ;     /L=F     - Поиск только файлов
              ;     /L=D     - Поиск только директорий
              ;     /L=DE    - Поиск только пустых директорий
              ;     /L=FDE   - Поиск пустых файлов и директорий
              ; /M=[mask]
              ;     /M=*.*         - поиск всех файлов (по-умолчанию)
              ;     /M=*.doc       - Поиск Work.doc, 1.doc ...
              ;     /M=Pho*        - Искать файлы в именах которых есть "Pho" (PHOTOS, phone.txt ...)
              ;     /M=win???.exe  - Поиск в имени "win" с 3 символами далее, только EXE (winamp.exe, winver.exe ...)
              ;     /M=winamp.exe  - Поиск только winamp.exe
              ; /S=No:No[B|K|M|G]
              ;     /S=      - Не определять размер файла (быстрее) (по-умолчанию)
              ;     /S=0:0B  - Найти файлы размер которых ровно 0 байтов
              ;     /S=5:9K  - Найти файлы от 5 до 9 Килобайт
              ;     /S=:10M  - Найти файлы размером 10 Мегабайт и меньше
              ;     /S=1G    - Найти файлы от 1 Гигабайта и более
              ; /G=[1|0]
              ;     /G=1     - Искать в поддиректориях (по-умолчанию)
              ;     /G=0     - Не искать в подкаталогах
              ; /B=[0|1]
              ;     /B=0     - Не показывать баннер прогресса (по умолчанию)
              ;     /B=1     - Показывать баннер.
              ;               
"Function"    ; Функция для вызова

Function "Function"
    ; $R9    "путь\имя"
    ; $R8    "путь"
    ; $R7    "имя"
    ; $R6    "размер"  ($R6="" если директория, $R6="0" если поиск с ключем /S=)

    ; $R0-$R5  не используется функцией.
    ; ...

    Push $var    ; Если $var="StopLocate" Завершение функции
FunctionEnd


Теперь примерчики:
1. Поиск одного файла
Section
    ${Locate} "C:\ftp" "/L=F /M=RPC DCOM.rar /S=1K" "Example1"
    ; Поиск 'RPC DCOM.rar' файла в папке 'C:\ftp' с размером 1 Kb или больше

    IfErrors 0 +2
    MessageBox MB_OK "Ошибка" 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$\nИскать дальше?' IDYES +2
    StrCpy $0 StopLocate

    Push $0
FunctionEnd

2. Запись результата в TXT файл
Section
    GetTempFileName $R0
    FileOpen $R1 $R0 w
    ${Locate} "C:\ftp" "/S=:2M /G=0" "Example2"
    ; папки файлы размером 2 Mb и меньше
    ; не искать в директориях
    FileClose $R1

    IfErrors 0 +2
    MessageBox MB_OK "Ошибка" IDOK +2
    Exec '"notepad.exe" "$R0"'
SectionEnd

Function Example2
    StrCmp $R6 '' 0 +3
    FileWrite $R1 "Директория=$R9$\r$\n"
    goto +2
    FileWrite $R1 "Файл=$R9  Размер=$R6 Mb$\r$\n"

    Push $0
FunctionEnd

3. Запись результата в INI файл
Section
    GetTempFileName $R0
    ${Locate} "C:\ftp" "/L=F /S=0K" "Example3"
    ; Все файлы в папке 'C:\ftp' с определением размеров в Kb

    IfErrors 0 +2
    MessageBox MB_OK "Ошибка" IDOK +2
    Exec '"notepad.exe" "$R0"'
SectionEnd

Function Example3
    WriteINIStr $R0 "$R8" "$R7" "$R6 Kb"

    Push $0
FunctionEnd

4. Удаляем пустые директории
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 'ошибка' IDOK +2
    MessageBox MB_OK '$R2 директорий удалено$\n$R3 loops'
SectionEnd

Function Example4
    MessageBox MB_YESNOCANCEL 'Удалить пустой каталог "$R9"?' IDNO end IDCANCEL cancel
    RMDir $R9
    IntOp $R1 $R1 + 1
    goto end

    cancel:
    StrCpy $R0 StopLocate

    end:
    Push $R0
FunctionEnd

5. Перемещаем все файлы в 1 каталог
Section
    StrCpy $R0 "C:\ftp"   ;Исходная директория (откуда перемещать)
    StrCpy $R1 "C:\ftp2"  ;Конечная директория (куда перемещать)

    StrCpy $R2 0
    StrCpy $R3 0
    ${Locate} "$R0" "/L=F" "Example5"

    IfErrors 0 +2
    MessageBox MB_OK 'ошибка' IDOK +4
    StrCmp $R3 0 0 +2
    MessageBox MB_OK '$R2 файлов перемещено' IDOK +2
    MessageBox MB_OK '$R2 файлов перемещено$\n$R3 файлов НЕ перемещено'
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

6. Копируем файлы, записывая результат в лог файл
Section
    StrCpy $R0 "C:\ftp"   ;Исходная директория (откуда копировать)
    StrCpy $R1 "C:\ftp2"  ;Конечная директория (куда копировать)
    StrLen $R2 $R0

    GetTempFileName $0
    FileOpen $R3 $0 w
    ${Locate} "$R0" "/L=FDE" "Example6"
    FileClose $R3

    IfErrors 0 +2
    MessageBox MB_OK 'ошибка'

    Exec '"notepad.exe" "$0"'     ;показываем лог файл
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 "-старый:$R9  -новый:$R1$1\$R7  -успешно$\r$\n"
    goto +2
    FileWrite $R3 "-старый:$R9  -новый:$R1$1\$R7  -ошибка$\r$\n"

    end:
    Push $0
FunctionEnd

7. Создание структуры каталогов
Section
    StrCpy $R0 "C:\ftp"     ;C какой директории будем снимать "слепок" структуры директорий
    StrCpy $R1 "C:\ftp2"    ;Помещаем "слепок" в данную директорию
    StrLen $R2 $R0

    ${Locate} "$R0" "/L=D" "Example7"

    IfErrors 0 +2
    MessageBox MB_OK 'ошибка'
SectionEnd

Function Example7
    StrCpy $1 $R9 '' $R2
    CreateDirectory '$R1$1'

    Push $0
FunctionEnd

8. Поиск файлов с показом баннера прогресса (необходимо наличие NxS плагина)
Section
    nxs::Show /NOUNLOAD `$(^Name) Setup` /top `Инсталлятор производит поиск$\r$\nПодождите...` /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