Что нового

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

DyadyaGenya

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

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

Вложения

  • буферизация.jpg
    буферизация.jpg
    31.6 КБ · Просмотры: 6

joiner

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

Вложения

  • Безымянный.jpg
    Безымянный.jpg
    24.5 КБ · Просмотры: 13
Автор
D

DyadyaGenya

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

joiner

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

DyadyaGenya

Знающий
Сообщения
300
Репутация
10
если уж есть опыт портирования кода, то и остальное найдется
Маленький у меня опыт ))) Пока иду двумя путями параллельно ) Запускаю секундомер "собственного написания" и пробую запустить сторонний, нажав на кнопку. В обоих случаях пока проблемы.
В первом либо стартует процесс копирования, а часы висят пока не закончиться копирование и только потом начинают тикать, либо идет секундомер, но копирование не идет.
Код:
#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,556
Репутация
628
как пример
можно запустить процесс копирования, остановить
Код:
#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

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

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
дело в том, что при запуске системного процесса копирования происходит блокировка процесса 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

Знающий
Сообщения
300
Репутация
10
дело в том, что при запуске системного процесса копирования происходит блокировка процесса 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,556
Репутация
628
все можно. или почти все
попробуй заменить основной цикл на этот
Код:
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

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

joiner

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

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

DyadyaGenya

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

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

Вложения

  • ошибка2.jpg
    ошибка2.jpg
    26.6 КБ · Просмотры: 1
Последнее редактирование:

joiner

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

DyadyaGenya

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

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

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
внес еще правки. добавил миллисекунды
допишешь обнуление полей ввода
Код:
#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

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

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

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

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
не выходит из цикла получения окна
попробуй заменить секцию
Код:
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

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

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

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
для скриншота окна прогресса и вставки в окно скрипта
Код:
#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
 
Последнее редактирование:
Верх