Что нового

Копирование папки, отображение процесса загрузки буфера и подсчет времени потраченного на процесс (секундомер)

Пост номер 16 был отмечен как лучший ответ.

DyadyaGenya

Новичок
Сообщения
100
Репутация
0
Доброго времени суток всем. В автоматизации не силен. Но появилась задача копировать папку с файлами через проводник, потому что только в проводнике показывает загрузку буфера как во вложении. При этом нужно подсчитывать время, затраченное на копирование. Так сказать: запускать секундомер. Можно и виндовый, но мне больше понравился сторонний Free Stopwatch в том числе и из-за портативности в коробке.
Обычная команда DirCopy ( "source dir", "dest dir" [, flag = 0 ] ) просто копирует, но процесс не отображается. Попробовал открыть папку в проводнике командой ShellExecute("$dir") папка открывается, но у меня не получается выделить в ней содержимое.
Ещё получается запустить поверх всех окон секундомер командой
Код:
Run ( "dirname\FreeStopwatch.exe","")
WinWait("")
WinSetOnTop("","",1)

Но не получается нажать кнопку старта и остановки времени.
Просьба показать, как оно должно быть. В плане секундомера можно предложить другой.
 

Вложения

joiner

Модератор
Локальный модератор
Сообщения
3 315
Репутация
566
а обычная полоса прогресса не подходит? насчет времени, то это весьма условно.
можно так
 

Вложения

Автор
D

DyadyaGenya

Новичок
Сообщения
100
Репутация
0
а обычная полоса прогресса не подходит?
Нет, нужен именно процесс загрузки буфера. В принципе этот шаг уже прошел. Подсказали, направили и получилось парой способов. Пример взял отсюда и перенес в autoit. Теперь осталось увязать с запуском секундомера
 

joiner

Модератор
Локальный модератор
Сообщения
3 315
Репутация
566
ну так в чем проблема? если уж есть опыт портирования кода, то и остальное найдется. секундомер это дело математики. скорость копирования - отсюда и исходим
 
Автор
D

DyadyaGenya

Новичок
Сообщения
100
Репутация
0
если уж есть опыт портирования кода, то и остальное найдется
Маленький у меня опыт ))) Пока иду двумя путями параллельно ) Запускаю секундомер "собственного написания" и пробую запустить сторонний, нажав на кнопку. В обоих случаях пока проблемы.
В первом либо стартует процесс копирования, а часы висят пока не закончиться копирование и только потом начинают тикать, либо идет секундомер, но копирование не идет.
Код:
#include <GUIConstantsEx.au3>
#include <Date.au3>

Run ( "путь\FreeStopwatch.exe","")
WinWait("")
WinSetOnTop("","",1)

Opt("TrayIconDebug", 1)

Global $timer, $Secs, $Mins, $Hour, $Time

_Main()

Func _Main()
    ;Создание GUI
    GUICreate("Секундомер", 500, 500)

    GUICtrlCreateLabel("00:00:00", 20, 20, 400, 200)
    GUICtrlSetFont(-1, 50, -1, -1, 'Impact')

    GUISetState()
    ;Старт таймера
    $timer = TimerInit()
    AdlibRegister("Timer", 100)


    While 1
        ;FileWriteLine("debug.log",@min & ":" & @sec & " ==> до")
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                Exit
                         $Shell = ObjCreate('Shell.Application')
                        $Shell.NameSpace('куда').CopyHere('откуда', 24)
        EndSwitch
        ;FileWriteLine("debug.log",@min & ":" & @sec & " ==> после")
     WEnd



EndFunc   ;==>_Main

Func Timer()
    _TicksToTime(Int(TimerDiff($timer)), $Hour, $Mins, $Secs)
    Local $sTime = $Time  ; сохраняет текущее время для проверки и избегания мерцания таймера...
    $Time = StringFormat("%02i:%02i:%02i", $Hour, $Mins, $Secs)
    If $sTime <> $Time Then ControlSetText("Секундомер", "", "Static1", $Time)
EndFunc   ;==>Timer


Во втором случае пока не полностью разобрался как нажать кнопку в каком-нибудь окошке любой программы. Для примера имею два секундомера
Сообщение автоматически объединено:

Вернее во втором случае не знаю как нажать на вторую кнопку, когда закончиться процесс копирования. Стартануть секундомер получается. А вот как его оставновить?
 
Последнее редактирование:

joiner

Модератор
Локальный модератор
Сообщения
3 315
Репутация
566
как пример
можно запустить процесс копирования, остановить
Код:
#pragma compile(AutoItExecuteAllowed, true)
#include <GUIConstantsEx.au3>
#include <Date.au3>
#include <WindowsConstants.au3>
#include <Timers.au3>

Global $timer, $Secs, $Mins, $Hour, $Time, $sTime, $TimeInf

Global $hGui = GUICreate("Секундомер", 500, 500)

$TimeInf = GUICtrlCreateLabel("00:00:00", 20, 20, 400, 200)
GUICtrlSetFont(-1, 50, -1, -1, 'Impact')
Local $btStart = GUICtrlCreateButton('start', 20, 300, 70, 25)
Local $btStop = GUICtrlCreateButton('stop', 20, 350, 70, 25)

GUISetState()
Global $iPid, $iTM

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            FileDelete('copy.txt')
            _Timer_KillTimer($hGui, $iTM)
            ProcessClose($iPid)
            Exit
        Case $btStart
            GUICtrlSetData($TimeInf, '00:00:00')
            FileWrite('copy.txt', "$Shell = ObjCreate('Shell.Application')" & @CRLF & "$Shell.NameSpace('путь к папке назначения').CopyHere('путь к копируемой папке', 24)")
            $timer = TimerInit()
            $iTM = _Timer_SetTimer($hGui, 10, "_TIMER")
            $iPid = Run(@AutoItExe & ' /AutoIt3ExecuteScript copy.txt')
        Case $btStop
            FileDelete('copy.txt')
            _Timer_KillTimer($hGui, $iTM)
            ProcessClose($iPid)
            GUICtrlSetData($TimeInf, '00:00:00')
    EndSwitch
WEnd

Func _TIMER($hWnd, $iMsg, $iIDTimer, $iTime)
    If Not ProcessExists($iPid) Then
        FileDelete('copy.txt')
        _Timer_KillTimer($hGui, $iTM)
    EndIf
    _TicksToTime(Int(TimerDiff($timer)), $Hour, $Mins, $Secs)
    $Time = StringFormat("%02i:%02i:%02i", $Hour, $Mins, $Secs)
    If $sTime <> $Time Then
        $sTime = $Time
        GUICtrlSetData($TimeInf, $Time)
    EndIf
EndFunc   ;==>_TIMER
 
Последнее редактирование:
Автор
D

DyadyaGenya

Новичок
Сообщения
100
Репутация
0
Работает )) Правда в таком случае сразу захотелось сделать кнопку выбора папки для копирования ))) и сделать милисекунды... Что-то у меня не получилось их прикрутить.
А это зачем? В том плане, что вообще зачем манипуляции с этим файлом и где он лежит?
 
Последнее редактирование:

joiner

Модератор
Локальный модератор
Сообщения
3 315
Репутация
566
дело в том, что при запуске системного процесса копирования происходит блокировка процесса autoit
значит, копирование нужно запустить в отдельном процессе. в файл записываются команды копирования и этот код запускается тем же самым модулем Autoit, которые составляет основной код.
Сообщение автоматически объединено:

пример с выбором пути.
кнопки без надписи
1. выбор копируемой папки
2.выбор папки назначения
Код:
#pragma compile(AutoItExecuteAllowed, true)
#include <GUIConstantsEx.au3>
#include <Date.au3>
#include <WindowsConstants.au3>
#include <Timers.au3>
#include <StaticConstants.au3>


Global $timer, $Secs, $Mins, $Hour, $Time, $sTime, $TimeInf, $sPS, $sPD
Global $iPid, $iTM
$hGui = GUICreate('Секундомер', 500, 170, @DesktopWidth - 500, 0)
$TimeInf = GUICtrlCreateLabel('00:00:00', 8, 8, 325, 81, $SS_CENTERIMAGE + $SS_CENTER, $WS_EX_STATICEDGE)
GUICtrlSetFont(-1, 50, -1, -1, 'Impact')
Local $btStart = GUICtrlCreateButton('Старт', 392, 8, 75, 25)
Local $btStop = GUICtrlCreateButton('Стоп', 392, 48, 75, 25)
Local $sPathSS = GUICtrlCreateInput('', 8, 96, 325, 21)
Local $sPathDD = GUICtrlCreateInput('', 8, 128, 325, 21)
Local $sPathS = GUICtrlCreateButton('...', 392, 96, 75, 25)
Local $sPathD = GUICtrlCreateButton('...', 392, 128, 75, 25)

GUISetState()

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            FileDelete('copy.txt')
            _Timer_KillTimer($hGui, $iTM)
            ProcessClose($iPid)
            Exit
        Case $sPathS
            GUICtrlSetData($sPathSS, '')
            $sPS = FileSelectFolder('Выбор копируемой папки', '', 0, '', $hGui)
            If Not @error Then GUICtrlSetData($sPathSS, $sPS)
        Case $sPathD
            GUICtrlSetData($sPathDD, '')
            $sPD = FileSelectFolder('Выбор папки назначения', '', 0, '', $hGui)
            If Not @error Then GUICtrlSetData($sPathDD, $sPD)
        Case $btStart
            If Not ProcessExists($iPid) Then
                If FileExists($sPS) And FileExists($sPD) Then
                    GUICtrlSetData($TimeInf, '00:00:00')
                    FileWrite('copy.txt', "$Shell = ObjCreate('Shell.Application')" & @CRLF & "$Shell.NameSpace('" & $sPD & "').CopyHere('" & $sPS & "', 24)")
                    $timer = TimerInit()
                    $iTM = _Timer_SetTimer($hGui, 10, '_TIMER')
                    $iPid = Run(@AutoItExe & ' /AutoIt3ExecuteScript copy.txt')
                EndIf
            EndIf
        Case $btStop
            FileDelete('copy.txt')
            _Timer_KillTimer($hGui, $iTM)
            ProcessClose($iPid)
            GUICtrlSetData($TimeInf, '00:00:00')
            $iPid = 0
    EndSwitch
WEnd

Func _TIMER($hWnd, $iMsg, $iIDTimer, $iTime)
    If Not ProcessExists($iPid) Then
        FileDelete('copy.txt')
        _Timer_KillTimer($hGui, $iTM)
        $iPid = 0
    EndIf
    _TicksToTime(Int(TimerDiff($timer)), $Hour, $Mins, $Secs)
    $Time = StringFormat('%02i:%02i:%02i', $Hour, $Mins, $Secs)
    If $sTime <> $Time Then
        $sTime = $Time
        GUICtrlSetData($TimeInf, $Time)
    EndIf
EndFunc   ;==>_TIMER
 
Последнее редактирование:
Автор
D

DyadyaGenya

Новичок
Сообщения
100
Репутация
0
дело в том, что при запуске системного процесса копирования происходит блокировка процесса autoit
значит, копирование нужно запустить в отдельном процессе. в файл записываются команды копирования и этот код запускается тем же самым модулем Autoit, которые составляет основной код.
Почти понял... А где лежит этот файл? Интересно посмотреть на его содержимое, что и как оно пишет. Вдруг получиться ещё и выцепить максимальную и минимальную скорость копирования. Ведь скорость скачет, особенно после переполнения буфера.
И продолжаю наглеть с хотелками )))
Чуток подправил вот этот кусок, чтоб по нажатию "стоп" очищалось поле ввода пути
Код:
Case $btStop
            FileDelete('copy.txt')
            _Timer_KillTimer($hGui, $iTM)
            ProcessClose($iPid)
            GUICtrlSetData($TimeInf, '00:00:00')
            GUICtrlSetData($sPathSS, '')
            GUICtrlSetData($sPathDD, '')
            $iPid = 0

А можно как-то ещё и запоминать выбор, чтоб типа выпадающего списка было? Это я так понимаю, нужен отдельный кэйс? Что-то он у меня сходу не получился
Но больше интересуют милисекунды
 
Последнее редактирование:

joiner

Модератор
Локальный модератор
Сообщения
3 315
Репутация
566
все можно. или почти все
попробуй заменить основной цикл на этот
Код:
While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            FileDelete('copy.txt')
            _Timer_KillTimer($hGui, $iTM)
            ProcessClose($iPid)
            Exit
        Case $sPathS
            GUICtrlSetData($sPathSS, '')
            $sPS = FileSelectFolder('Выбор копируемой папки', '', 0, '', $hGui)
            If Not @error Then GUICtrlSetData($sPathSS, $sPS)
        Case $sPathD
            GUICtrlSetData($sPathDD, '')
            $sPD = FileSelectFolder('Выбор папки назначения', '', 0, '', $hGui)
            If Not @error Then GUICtrlSetData($sPathDD, $sPD)
        Case $btStart
            If Not ProcessExists($iPid) Then
                If FileExists($sPS) And FileExists($sPD) Then
                    GUICtrlSetData($TimeInf, '00:00:00')
                    FileWrite('copy.txt', "$Shell = ObjCreate('Shell.Application')" & @CRLF & "$Shell.NameSpace('" & $sPD & "').CopyHere('" & $sPS & "', 24)")
                    $timer = TimerInit()
                    $iTM = _Timer_SetTimer($hGui, 10, '_TIMER')
                    $iPid = Run(@AutoItExe & ' /AutoIt3ExecuteScript copy.txt')
                    While 1
                        If ProcessExists($iPid) Then
                            $ahWin = _WinAPI_EnumProcessWindows($iPid)
                            If Not @error Then ExitLoop
                        EndIf
                    WEnd
                    WinMove(HWnd($ahWin[1][0]), '', @DesktopWidth - 500, 200)
                EndIf
            EndIf
        Case $btStop
            FileDelete('copy.txt')
            _Timer_KillTimer($hGui, $iTM)
            ProcessClose($iPid)
            GUICtrlSetData($TimeInf, '00:00:00')
            $iPid = 0
    EndSwitch
WEnd

в блокнот пишет вот это
Код:
$Shell = ObjCreate('Shell.Application')
$Shell.NameSpace('куда').CopyHere('откуда', 24)
 
Автор
D

DyadyaGenya

Новичок
Сообщения
100
Репутация
0
попробуй заменить основной цикл на этот
Выдало ошибку после начала копирования, ругается на неизвестную функцию $ahWin = _WinAPI_EnumProcessWindows($iPid)
Но благодаря ей увидел оставшийся файл copy.txt
 

joiner

Модератор
Локальный модератор
Сообщения
3 315
Репутация
566
Миллисекунды будут мерцать. Что дает визуальное мелькание цифр?
Сообщение автоматически объединено:

В справке по языку найди эту функцию. Там будет название полключаемой udf. Допиши ее в код. У меня версия автоит другая
 
Автор
D

DyadyaGenya

Новичок
Сообщения
100
Репутация
0
Миллисекунды будут мерцать. Что дает визуальное мелькание цифр?
Честно говоря, не видел как они будут мерцать. Возможно поэтому кажется, что так было бы ещё прикольней. По идее должны бежать как в том стороннем секундомере, что я приводил. Само то четвертое "поле" под милисекунды выводиться, но при старте выдает ошибку.
Со справкой буду разбираться.
Только сейчас обратил внимание, что сам секундомер не висит поверх всех окон, как я пробовал сделать со сторонним секундомером. А хотелось бы, но пока не получается
И как оставить окошко копирования после окончания копирования? Чтоб оставалось окно секундомера и рядом окно копирования
В справке по языку найди эту функцию. Там будет название полключаемой udf. Допиши ее в код. У меня версия автоит другая
Оказалось, что нужно было добавить инклуде
Код:
#include <WinAPIProc.au3>

Правда после этого выдало другую ошибку
Поправка. Вдруг сама по себе эта ошибка исчезла. Но список файлов не появился
 

Вложения

Последнее редактирование:

joiner

Модератор
Локальный модератор
Сообщения
3 315
Репутация
566
И как оставить окошко копирования после окончания копирования? Чтоб оставалось окно секундомера и рядом окно копирования
тут я не знаю. мы же вызываем системное окно(функцию). в ней предусмотрено закрытие, как я понимаю.
 
Автор
D

DyadyaGenya

Новичок
Сообщения
100
Репутация
0
А с окошком секундомера, чтоб был по центру монитора и всегда поверх других окон можете подсказать?
Я пробовал использовать $WS_EX_TOPMOST но пока не получается. Сместить само окошко на определенное число пикселей можно, но хотелось бы в процентах, а такой опции не могу найти

И ещё, странное дело, но когда запускаю скрипт, то в других приложениях невозможно вызвать контекстное меню правой кнопки. Появляется и тут же исчезает...
 
Последнее редактирование:

joiner

Модератор
Локальный модератор
Сообщения
3 315
Репутация
566
внес еще правки. добавил миллисекунды
допишешь обнуление полей ввода
Код:
#pragma compile(AutoItExecuteAllowed, true)
#RequireAdmin
#include <GUIConstantsEx.au3>
#include <Date.au3>
#include <WindowsConstants.au3>
#include <Timers.au3>
#include <StaticConstants.au3>
#include <WinAPIProc.au3>


Global $timer, $Secs, $Mins, $Hour, $Time, $sTime, $TimeInf, $sPS, $sPD
Global $iPid, $iTM
$hGui = GUICreate('Секундомер', 500, 170, -1, -1, -1, $WS_EX_TOPMOST)
$TimeInf = GUICtrlCreateLabel('00:00:00:000', 8, 8, 330, 81, $SS_CENTERIMAGE + $SS_CENTER, $WS_EX_STATICEDGE)
GUICtrlSetFont(-1, 36, -1, -1, 'Impact')
Local $btStart = GUICtrlCreateButton('Старт', 392, 8, 75, 25)
Local $btStop = GUICtrlCreateButton('Стоп', 392, 48, 75, 25)
Local $sPathSS = GUICtrlCreateInput('', 8, 96, 325, 21)
Local $sPathDD = GUICtrlCreateInput('', 8, 128, 325, 21)
Local $sPathS = GUICtrlCreateButton('...', 392, 96, 75, 25)
Local $sPathD = GUICtrlCreateButton('...', 392, 128, 75, 25)

GUISetState()

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            FileDelete('copy.txt')
            _Timer_KillTimer($hGui, $iTM)
            ProcessClose($iPid)
            Exit
        Case $sPathS
            GUICtrlSetData($sPathSS, '')
            $sPS = FileSelectFolder('Выбор копируемой папки', '', 0, '', $hGui)
            If Not @error Then GUICtrlSetData($sPathSS, $sPS)
        Case $sPathD
            GUICtrlSetData($sPathDD, '')
            $sPD = FileSelectFolder('Выбор папки назначения', '', 0, '', $hGui)
            If Not @error Then GUICtrlSetData($sPathDD, $sPD)
        Case $btStart
            FileDelete('copy.txt')
            If Not ProcessExists($iPid) Then
                If FileExists($sPS) And FileExists($sPD) Then
                    GUICtrlSetData($TimeInf, '00:00:00:000')
                    FileWrite('copy.txt', "$Shell = ObjCreate('Shell.Application')" & @CRLF & "$Shell.NameSpace('" & $sPD & "').CopyHere('" & $sPS & "', 24)")
                    $timer = TimerInit()
                    $iTM = _Timer_SetTimer($hGui, 50, '_TIMER')
                    $iPid = Run(@AutoItExe & ' /AutoIt3ExecuteScript copy.txt')
                    While 1
                        If ProcessExists($iPid) Then
                            $ahWin = _WinAPI_EnumProcessWindows($iPid)
                            If Not @error Then
                                Local $aPosP = WinGetPos($hGui)
                                WinSetOnTop($ahWin[1][0], '', 1)
                                WinMove($ahWin[1][0], '', $aPosP[0], $aPosP[1] + $aPosP[3] - 30)
                                WinSetOnTop($hGui, '', 1)
                                ExitLoop
                            EndIf
                        EndIf
                    WEnd
                    FileDelete('copy.txt')
                EndIf
            EndIf
        Case $btStop
            FileDelete('copy.txt')
            _Timer_KillTimer($hGui, $iTM)
            ProcessClose($iPid)
            GUICtrlSetData($TimeInf, '00:00:00:000')
            $iPid = 0
    EndSwitch
WEnd

Func _TIMER($hWnd, $iMsg, $iIDTimer, $iTime)
    If Not ProcessExists($iPid) Then
        FileDelete('copy.txt')
        _Timer_KillTimer($hGui, $iTM)
        $iPid = 0
    EndIf
    _TicksToTime(Int(TimerDiff($timer)), $Hour, $Mins, $Secs)
    $Time = StringFormat('%02i:%02i:%02i:%03i', $Hour, $Mins, $Secs, StringRight(Int(TimerDiff($timer)), 3))
    GUICtrlSetData($TimeInf, $Time)
EndFunc   ;==>_TIMER
насчет контекстного меню не могу сказать. у меня все работает. только дольше вызывается, так как идет копирование
 
Автор
D

DyadyaGenya

Новичок
Сообщения
100
Репутация
0
внес еще правки. добавил миллисекунды
Спасибо. Работает ) Получается милисекунды реализованы строкой?
Код:
$Time = StringFormat('%02i:%02i:%02i:%03i', $Hour, $Mins, $Secs, StringRight(Int(TimerDiff($timer)), 3))

И теперь понял, почему у меня поверх окон не получалось ))) и по центру )
насчет контекстного меню не могу сказать. у меня все работает.
Странно, в этом варианте и у меня работает. Запустил предыдущую версию - исчезает.
Сообщение автоматически объединено:

допишешь обнуление полей ввода
Вылез небольшой нюанс с моим вариантом обнуления полей ввода. Почему-то на очень маленьких объемах копируемых файлов, когда процес занимает до 2сек, после копирования не обнуляются поля и нельзя закрыть окошко секундомера. Видимо связано с тем, что окно самого процесса копирования мелькает и тут же исчезает или вообще на появляется. Но это не страшно, просто странно и хотелось понять причины.
 
Последнее редактирование:

joiner

Модератор
Локальный модератор
Сообщения
3 315
Репутация
566
не выходит из цикла получения окна
попробуй заменить секцию
Код:
Case $btStart

вот на это
Код:
Case $btStart
            FileDelete('copy.txt')
            If Not ProcessExists($iPid) Then
                If FileExists($sPS) And FileExists($sPD) Then
                    GUICtrlSetData($TimeInf, '00:00:00:000')
                    FileWrite('copy.txt', "$Shell = ObjCreate('Shell.Application')" & @CRLF & "$Shell.NameSpace('" & $sPD & "').CopyHere('" & $sPS & "', 24)")
                    $timer = TimerInit()
                    $iTM = _Timer_SetTimer($hGui, 50, '_TIMER')
                    $iPid = Run(@AutoItExe & ' /AutoIt3ExecuteScript copy.txt')
                    If ProcessExists($iPid) Then
                        While 1
                            Local $ahWin = _WinAPI_EnumProcessWindows($iPid)
                            If Not @error Then
                                If Not StringInStr($ahWin[1][1], 'Autoit') Then
                                    Local $aPosP = WinGetPos($hGui)
                                    WinSetOnTop($ahWin[1][0], '', 1)
                                    WinMove($ahWin[1][0], '', $aPosP[0], $aPosP[1] + $aPosP[3] - 30)
                                    WinSetOnTop($hGui, '', 1)
                                EndIf
                                ExitLoop
                            EndIf
                        WEnd
                    EndIf
                    FileDelete('copy.txt')
                EndIf
            EndIf
 
Автор
D

DyadyaGenya

Новичок
Сообщения
100
Репутация
0
попробуй заменить секцию
Сработало )
Но у меня как в поговорке ))) аппетит приходит во время еды )))
Сейчас задумался как вывести температуру диска и максимальную и минимальную скорости копирования. А там, глядишь, и переделаю процесс копирования, чтоб получить полный контроль и оставлять его рядом с секундомером. Сижу, мучаю. Как пойму, что устал и нет мыслей, начну новую тему )
Правда появилась мысль заскринить конец копирования и вставить в поле секундомера. Но пока только мысли...
Сообщение автоматически объединено:

можно запустить процесс копирования, остановить
Таки вернулся к этому вопросу. Вроде приблизительно понятно, как организовано прерывание одного процесса и запуск другого. Если не сложно, поясните более подробно ваш вариант и можно ли к нему прикрутить запуск функции.
Попробовал для дальнейшей визуализации процесса запустить функцию создания скрина. Но, если записать вызов в файл "copy.txt", то ругается на неизвестную функцию. Если добавить в инклуде, то сразу ругается, что процесс копирования не начат и скрипт закрывается. Если добавлять вызов функции где-то после запуска содержимого "copy.txt" то выскакивают другие ошибки, либо просто не делает скрин нужной области.
 
Последнее редактирование:

joiner

Модератор
Локальный модератор
Сообщения
3 315
Репутация
566
для скриншота окна прогресса и вставки в окно скрипта
Код:
#pragma compile(AutoItExecuteAllowed, true)
#RequireAdmin
#include <GUIConstantsEx.au3>
#include <Date.au3>
#include <WindowsConstants.au3>
#include <Timers.au3>
#include <StaticConstants.au3>
#include <WinAPIProc.au3>
#include <ScreenCapture.au3>

Global $timer, $Secs, $Mins, $Hour, $Time, $sTime, $TimeInf, $sPS, $sPD
Global $iPid, $iTM, $hTitleProc, $iProcWinH, $iProcWinW, $sPathSC = @TempDir & '\test.jpg'
$hGui = GUICreate('Секундомер', 500, 170, -1, -1, -1, $WS_EX_TOPMOST)
$TimeInf = GUICtrlCreateLabel('00:00:00:000', 8, 8, 330, 81, $SS_CENTERIMAGE + $SS_CENTER, $WS_EX_STATICEDGE)
GUICtrlSetFont(-1, 36, -1, -1, 'Impact')
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKTOP + $GUI_DOCKHEIGHT)
Local $btStart = GUICtrlCreateButton('Старт', 392, 8, 75, 25)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKTOP + $GUI_DOCKHEIGHT)
Local $btStop = GUICtrlCreateButton('Стоп', 392, 48, 75, 25)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKTOP + $GUI_DOCKHEIGHT)
Local $sPathSS = GUICtrlCreateInput('', 8, 96, 325, 21)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKTOP + $GUI_DOCKHEIGHT)
Local $sPathDD = GUICtrlCreateInput('', 8, 128, 325, 21)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKTOP + $GUI_DOCKHEIGHT)
Local $sPathS = GUICtrlCreateButton('...', 392, 96, 75, 25)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKTOP + $GUI_DOCKHEIGHT)
Local $sPathD = GUICtrlCreateButton('...', 392, 128, 75, 25)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKTOP + $GUI_DOCKHEIGHT)
Global $iPS = GUICtrlCreatePic('', 20, 150, 100, 100)
GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKTOP + $GUI_DOCKHEIGHT)

GUISetState()

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            FileDelete('copy.txt')
            _Timer_KillTimer($hGui, $iTM)
            ProcessClose($iPid)
            Exit
        Case $sPathS
            GUICtrlSetData($sPathSS, '')
            $sPS = FileSelectFolder('Выбор копируемой папки', '', 0, '', $hGui)
            If Not @error Then GUICtrlSetData($sPathSS, $sPS)
        Case $sPathD
            GUICtrlSetData($sPathDD, '')
            $sPD = FileSelectFolder('Выбор папки назначения', '', 0, '', $hGui)
            If Not @error Then GUICtrlSetData($sPathDD, $sPD)
        Case $btStart
            Local $aPosP = WinGetPos($hGui)
            GUICtrlSetImage($iPS, '')
            WinMove($hGui, '', $aPosP[0], $aPosP[1], $aPosP[2], $aPosP[3] - $iProcWinH)
            FileDelete('copy.txt')
            FileDelete($sPathSC)
            If Not ProcessExists($iPid) Then
                If FileExists($sPS) And FileExists($sPD) Then
                    GUICtrlSetData($TimeInf, '00:00:00:000')
                    FileWrite('copy.txt', "$Shell = ObjCreate('Shell.Application')" & @CRLF & "$Shell.NameSpace('" & $sPD & "').CopyHere('" & $sPS & "', 24)")
                    $timer = TimerInit()
                    $iTM = _Timer_SetTimer($hGui, 5, '_TIMER')
                    $iPid = Run(@AutoItExe & ' /AutoIt3ExecuteScript copy.txt')
                    If ProcessExists($iPid) Then
                        While 1
                            Local $ahWin = _WinAPI_EnumProcessWindows($iPid)
                            If Not @error Then
                                If Not StringInStr($ahWin[1][1], 'Autoit') Then
                                    $hTitleProc = $ahWin[1][0]
                                    Local $aPosC = WinGetPos($hTitleProc)
                                    $iProcWinW = $aPosC[2]
                                    $iProcWinH = $aPosC[3]
                                    GUICtrlSetPos($iPS, 20, 170, $iProcWinW, $iProcWinH)
                                    WinMove($hTitleProc, '', $aPosP[0] + 15, $aPosP[1] + $aPosP[3])
                                    WinSetOnTop($hTitleProc, '', 1)
                                EndIf
                                ExitLoop
                            EndIf
                        WEnd
                    EndIf
                    FileDelete('copy.txt')
                EndIf
            EndIf
        Case $btStop
            FileDelete('copy.txt')
            _Timer_KillTimer($hGui, $iTM)
            ProcessClose($iPid)
            GUICtrlSetData($TimeInf, '00:00:00:000')
            $iPid = 0
            Local $aPosP = WinGetPos($hGui)
            GUICtrlSetImage($iPS, '')
            WinMove($hGui, '', $aPosP[0], $aPosP[1], $aPosP[2], $aPosP[3] - $iProcWinH)
    EndSwitch
WEnd

Func _TIMER($hWnd, $iMsg, $iIDTimer, $iTime)
    Local $iProcC = Number(StringRegExpReplace(WinGetTitle($hTitleProc), '[^\d]', '\1'))
    If $iProcC > 90 Then
        _ProcessSuspend($hTitleProc, 1)
        _ScreenCapture_CaptureWnd($sPathSC, $hTitleProc, 0, 0, -1, -1, False)
        _ProcessSuspend($hTitleProc)
    EndIf
    If Not ProcessExists($iPid) Then
        If FileExists($sPathSC) Then
            WinMove($hGui, '', Default, Default, Default, 170 + $iProcWinH - 20)
            GUICtrlSetImage($iPS, $sPathSC)
        EndIf
        FileDelete('copy.txt')
        _Timer_KillTimer($hGui, $iTM)
        $iPid = 0
    EndIf
    _TicksToTime(Int(TimerDiff($timer)), $Hour, $Mins, $Secs)
    $Time = StringFormat('%02i:%02i:%02i:%03i', $Hour, $Mins, $Secs, StringRight(Int(TimerDiff($timer)), 3))
    GUICtrlSetData($TimeInf, $Time)
EndFunc   ;==>_TIMER

Func _ProcessSuspend($sProcess, $vProcSetState = False) ; $vProcSetState = True ; Приостанавливаем процесс
    Local $hProcess, $iSucess, $iPid = ProcessExists($sProcess)
    If Not $iPid Then Return SetError(1, 0, 0)
    $vProcSetState = ($vProcSetState) ? 'NtSuspendProcess' : 'NtResumeProcess'

    $hProcess = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, 0, $iPid)
    If @error Then Return SetError(2, 0, 0)
    $iSucess = DllCall('ntdll.dll', 'int', $vProcSetState, 'int', $hProcess)
    _WinAPI_CloseHandle($hProcess)
    If Not IsArray($iSucess) Then Return SetError(3, 0, 0)
    Return 1
EndFunc   ;==>_ProcessSuspend
 
Последнее редактирование:
Верх