Что нового

Autoit не видит окно?

TSV

Новичок
Сообщения
8
Репутация
0
Здравствуйте, извините за банальный вопрос, но я новичок:
скрипт запускает копирование папок и файлов (в проге Everything), и мне надо дождаться окончания копирования чтоб скрипт выполнялся далее...
Пробовал:
WinWaitActive ("Выполнено ", "")
WinWaitClose ("Выполнено ", "")
Скрипт зависает, видимо не находит окно "Выполнено ". Пробовал прописывать класс окна, но тоже безрезультатно.
Подскажите как можно решить... Может через процесс?
 

Вложения

  • 1.jpg
    1.jpg
    51.1 КБ · Просмотры: 8

AZJIO

Меценат
Меценат
Сообщения
2,900
Репутация
1,199
Может WinWait использовать?
Проверил WinWaitActive и WinWait оба отработали с окном отлично. Начал копировать фильм, запустил скрипт и при активации окна WinWaitActive его отловил, а WinWait сразу после появления.
Могу сказать что Windows10 сейчас поведение такое: если окно создающее другое окно было неактивно, то оно создаёт неактивное окно, как бы не забираю приоритет у активного окна. Поэтому причина может быть в том что созданное окно просто неактивно.
Ещё момент: желательно указывать время сколько скрипт будет ожидать активное окно, чтобы не заблокировать его навечно или не отработать через час с другим окном. Например 5-20 сек. У меня папка с 6000 файлов показало окно через секунду, то есть оно не собирало информацию о количестве файлов, а начало работать сразу, значит и функция не должна долго ждать появление окна.
 
Последнее редактирование:
Автор
T

TSV

Новичок
Сообщения
8
Репутация
0
Причина оказалась в том, что было еще одно скрытое окно "Выполнено 100%". По каким-то причинам Проводник скопировал файлы (проверил), но окно не закрылось, а стало скрытым...и штатными средствами не закрывается. Получилось убрать только после перезапуска Проводника. Скрипт работает весь день на работе, копируя сравнительно небольшие файлы и папки по локалке и периодически возникает эта ошибка.
 

Вложения

  • 2.png
    2.png
    21.9 КБ · Просмотры: 3
Автор
T

TSV

Новичок
Сообщения
8
Репутация
0
Дело в том, что мне нужен быстрый поиск по локальной сети на сервере (пользуюсь Everything), и мне необходимо скопировать все найденные папки и файлы в указанную папку. Как скопировать один объект встроенной командой мне понятно, а как несколько - нет...
 
Автор
T

TSV

Новичок
Сообщения
8
Репутация
0
Да, команду знаю, но как ее применить в случае, если программа поиска нашла например 15 элементов (все в разных местах). Мне надо их все скопировать, т.е. вставить в DirCopy пути, где они находятся. Я не знаю как записать цикл перебора, если заранее не знаю количество найденных объектов
 

All2khoff

Продвинутый
Сообщения
390
Репутация
72
Буквально на днях была тема где обсуждался глубокий поиск файлов...
туть
там не совсем то... но есть от чего отталкиваться.
Ну а если нужен более продуктивный подход, то нужно более подробное описание задачи)
 
Автор
T

TSV

Новичок
Сообщения
8
Репутация
0
Задача такая: найти (максимально быстро - пробую разные проги, в данный момент - Everything) и скопировать файлы (или папки) по локальной сети на удаленных серверах (на двух) в одну общую папку. На одном сервере объем для поиска большой, порядка 20 млн. файлов... Для копирования задействовал функционал Everything. Имена для поиска считываются из общедоступного файла. В принципе скрипт работает нормально, но иногда не происходит нормальное завершение работы, как будто ожидает чего-то...
 

All2khoff

Продвинутый
Сообщения
390
Репутация
72
Составляем массив существующих файлов и каталогов, а затем копируем нужные при совпадении имени файла или каталога в списке.txt.
Код:
#include <File.au3>
#include <Array.au3>

; Путь к файлу со списком
Local $filelistPath = @ScriptDir &"\filelist.txt"
; Папки для поиска
Local $searchDirs[2] = [ "\\PC-02\Distrib", "\\PC-02\Music" ]    ;перечисляем каталоги поиска
; Папка для копирования
Local $destinationDir = @ScriptDir &"\catalog"

; Создаем папку назначения, если она не существует
If Not FileExists($destinationDir) Then
    DirCreate($destinationDir)
EndIf

; Читаем список файлов и каталогов
Local $fileList = FileReadToArray($filelistPath)
If @error Then
    MsgBox(0, "Ошибка", "Не удалось прочитать файл filelist.txt")
    Exit
EndIf

; Функция для поиска и копирования файлов и каталогов
Func FindAndCopyFiles($searchDirs, $fileList, $destinationDir)
    For $i = 0 To UBound($searchDirs) - 1
        Local $searchDir = $searchDirs[$i]
        _SearchAndCopy($searchDir, $fileList, $destinationDir)
    Next
EndFunc

; Рекурсивная функция для поиска и копирования
Func _SearchAndCopy($currentDir, $fileList, $destinationDir)
    Local $hSearch = FileFindFirstFile($currentDir & "\*")
    If $hSearch = -1 Then Return

    While 1
        Local $file = FileFindNextFile($hSearch)
        If @error Then ExitLoop

        ; Полный путь к текущему файлу или каталогу
        Local $sourcePath = $currentDir & "\" & $file

        ; Проверяем, является ли это файлом или каталогом
        If StringInStr($file, ".") Then ; Это файл
            For $j = 0 To UBound($fileList) - 1
                If StringCompare($file, $fileList[$j]) = 0 Then
                    Local $destPath = $destinationDir & "\" & $file
                    FileCopy($sourcePath, $destPath, 1) ; 1 - перезаписать
                    ConsoleWrite("Скопирован файл: " & $sourcePath & " -> " & $destPath & @CRLF)
                EndIf
            Next
        Else ; Это каталог
            ; Проверяем, есть ли каталог в списке
            For $j = 0 To UBound($fileList) - 1
                If StringCompare($file, $fileList[$j]) = 0 Then
                    Local $destPath = $destinationDir & "\" & $file
                    If Not FileExists($destPath) Then
                        DirCreate($destPath) ; Создаем каталог в папке назначения
                    EndIf
                    ConsoleWrite("Скопирован каталог: " & $sourcePath & " -> " & $destPath & @CRLF)
                    ; Рекурсивный вызов для копирования содержимого каталога
                    _CopyDirectory($sourcePath, $destPath)
                EndIf
            Next
        EndIf
    WEnd

    FileClose($hSearch)
EndFunc

; Функция для рекурсивного копирования каталога
Func _CopyDirectory($sourceDir, $destDir)
    Local $hSearch = FileFindFirstFile($sourceDir & "\*")
    If $hSearch = -1 Then Return

    While 1
        Local $file = FileFindNextFile($hSearch)
        If @error Then ExitLoop

        Local $sourcePath = $sourceDir & "\" & $file
        Local $destPath = $destDir & "\" & $file

        If StringInStr($file, ".") Then ; Это файл
            FileCopy($sourcePath, $destPath, 1) ; 1 - перезаписать
            ConsoleWrite("Скопирован файл: " & $sourcePath & " -> " & $destPath & @CRLF)
        Else ; Это каталог
            If Not FileExists($destPath) Then
                DirCreate($destPath)
            EndIf
            ConsoleWrite("Скопирован каталог: " & $sourcePath & " -> " & $destPath & @CRLF)
            _CopyDirectory($sourcePath, $destPath)
        EndIf
    WEnd

    FileClose($hSearch)
EndFunc

; Запускаем поиск и копирование
FindAndCopyFiles($searchDirs, $fileList, $destinationDir)
 
Последнее редактирование:
Автор
T

TSV

Новичок
Сообщения
8
Репутация
0
Круто! Спасибо, буду пробовать - займет время... Но есть подозрения, что Autoit не сможет произвести поиск достаточно быстро (Everything сначала индексирует базу, и то поиск не мгновенный - примерно секунд 20...). Суть в том, что операторы на своих PC вводят необходимые имена (стандартизированные) для поиска и сохраняет файл - скрипт должен выдать результат как можно быстрее (скорость важна, т.к. за рабочий день ищется несколько сотен имен).
 

AZJIO

Меценат
Меценат
Сообщения
2,900
Репутация
1,199
У Everything есть SDK, API, т.е. возможность вызова функций из dll. Вроде как в этом случае не нужны внешние скрипты для работы с окнами.


но как ее применить в случае, если программа поиска нашла например 15 элементов (все в разных местах).

Есть функции захвата данных списка _GUICtrlListView_GetAllTextToArray
 
Последнее редактирование:
Автор
T

TSV

Новичок
Сообщения
8
Репутация
0
Как я понял из справки в Everything SDK через dll для работы по локальной сети необходимо запустить сервер ETP, такой возможности у меня нет...
 
Верх