Что нового

[Автоматизация] Остановка цикла по требованию

Dr.Freezer

Новичок
Сообщения
7
Репутация
0
Добрый день. Имеется проблема с остановкой цикла по нажатию кнопки. Реализовал остановку через переменную, первый раз остановка срабатывает, но если второй раз запустить цикл - скрипт уже ни на что не реагирует, пока не закончится цикл. По поиску примеры искал, но так и не вышло их адаптировать.

Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <StaticConstants.au3>
#Include <Encoding.au3>
#include <File.au3>
#include <GuiTab.au3>

Opt("GUIOnEventMode", 1)
$mainwindow = GUICreate("Windows 7 Deploy Module", 555, 480)
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")
#NoTrayIcon

$log = GUICtrlCreateEdit('', 0, 300, 555, 180)

;##################################################################################################################

$processor = RegRead ("HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0","ProcessorNameString")

GUICtrlCreateLabel ("Процессор:", 5, 32, 70, 50)
GUICtrlCreateLabel ("Машина:", 5, 62, 50, 50)
$processorinput = GUICtrlCreateCombo ( "", 75,30,250,20)
GUICtrlSetData(-1, "Intel(R) Pentium(R) CPU G2030 @ 3.00GHz|Intel(R) Core(TM)2 Duo CPU     E4500  @ 2.20GHz|Intel(R) Pentium(R) CPU G3220 @ 3.00GHz", $processor)
GUICTRLSetOnEvent($processorinput, "CPUSelect")
$machineinput = GUICtrlCreateInput ( "", 75,60,250,20, 0x800)
GUICtrlSetState ($processorinput, $GUI_DISABLE)
GUICtrlSetState ($machineinput, $GUI_DISABLE)

GUICtrlCreateGroup("Статус", 355, 23, 190, 200)
$statuscheck1 = GUICtrlCreateCheckbox ("Очистка диска", 365, 40, 120, 20)
$statuscheck2 = GUICtrlCreateCheckbox ("Развертывание образа", 365, 65, 175, 20)
$statuscheck3 = GUICtrlCreateCheckbox ("Загрузочная запись (MBR)", 365, 90, 175, 20)
$statuscheck4 = GUICtrlCreateCheckbox ("Удаление хвостов", 365, 115, 120, 20)
GUICtrlSetState ($statuscheck1, $GUI_DISABLE + $GUI_CHECKED)
GUICtrlSetState ($statuscheck2, $GUI_DISABLE + $GUI_CHECKED)
GUICtrlSetState ($statuscheck3, $GUI_DISABLE + $GUI_CHECKED)
GUICtrlSetState ($statuscheck4, $GUI_DISABLE + $GUI_CHECKED)
$progressbar1 = GUICtrlCreateProgress(365, 195, 172, 20)

;##################################################################################################################
global $cancelbutton1 = GUICtrlCreateButton ( "Отмена (Ручной режим)", 175, 200, 170, 25)
$startbutton1 = GUICtrlCreateButton ( "Запуск", 175, 200, 170, 25)
GUICtrlSetOnEvent($cancelbutton1, "CancelOperation")
GUICtrlSetOnEvent($startbutton1, "StartOperation")

GUISetState(@SW_SHOW)
;##################################################################################################################

StartOperation()

GUICtrlSetData($log, @CRLF & "Развертывание завершено" & @CRLF, 1)
GUICtrlSetData($log, "Запись log.txt..." & @CRLF, 1)
LogWrite()
;-====================================================- Functions
Func CPUSelect()
   global $processordata = GUICtrlRead($processorinput)
If $processordata = "Intel(R) Pentium(R) CPU G2030 @ 3.00GHz" Then
   GUICtrlSetData($machineinput, "HP 3500")
   $imageximage = 1
ElseIf $processordata = "Intel(R) Core(TM)2 Duo CPU     E4500  @ 2.20GHz" Then
   GUICtrlSetData($machineinput, "HP dx2300")
   $imageximage = 2
ElseIf $processordata = "Intel(R) Pentium(R) CPU G3220 @ 3.00GHz" Then
   GUICtrlSetData($machineinput, "HP Pro 400")
   $imageximage = 3
Else
EndIf
global $machinedata = GUICtrlRead($machineinput)
EndFunc

Func DeployConfig()
GUICtrlSetState ($startbutton1, $GUI_DISABLE)
GUICtrlSetState ($startbutton1, $GUI_HIDE)
GUICtrlSetState ($cancelbutton1, $GUI_SHOW)
GUICtrlSetState ($cancelbutton1, $GUI_ENABLE)

GUICtrlSetData($log, @CRLF & "Модель процессора: " & $processordata & @CRLF, 1)
GUICtrlSetData($log, "Модель машины: " & $machinedata & @CRLF, 1)

If GUICtrlRead($statuscheck1) = 1 Then
global $operation = "diskpart"
$diskpart = Run(@ComSpec & " /c ping 127.0.0.1 -n 6", @SystemDir, Default, 2)
Cycle($diskpart, 100, 12, 0)
GUICtrlSetState ($statuscheck1, $GUI_UNCHECKED)
GUICtrlSetData($progressbar1, 100)
EndIf
EndFunc

Func StartOperation()
   global $stop = False
   CPUSelect()
   DeployConfig()
EndFunc

Func Cycle($bluho, $percent, $speed, $progressi)
   $i = $progressi
While 1
   If GUIGetMsg() = $cancelbutton1 Or $stop Then ExitLoop
    $aRead = StdoutRead($bluho)
    If $aRead Then
        GUICtrlSetData($log, GUICtrlRead($log) & _Encoding_CyrillicTo1251($aRead))
		$i = $i + $speed
		 If $i < $percent Then
			GUICtrlSetData($progressbar1, $i)
		 ElseIF $i = $percent Then
			GUICtrlSetData($progressbar1, $percent)
		 EndIf
	  EndIf
	If @error or $stop = True Then
	   ExitLoop
	 EndIf
WEnd
EndFunc

Func LogWrite()
$logdata = GUICtrlRead($log)
_FileCreate ( "log.txt" )
FileOpen ("log.txt", 1)
FileWrite ("log.txt", $logdata)
FileClose ("log.txt")
EndFunc

Func CancelOperation()
   ;If $operation = "diskpart" Then
	;  ProcessClose ("diskpart.exe")
  ; ElseIF $operation = "imagex" Then
	;  ProcessClose ("imagex.exe")
   ;ElseIF $operation = "bootsect" Then
   ;EndIF
   
   global $stop = True
   
   If $operation = "diskpart" Then
	  ProcessClose ("cmd.exe")
   EndIF
   
   GUICtrlSetState ($cancelbutton1, $GUI_DISABLE)
   GUICtrlSetState ($cancelbutton1, $GUI_HIDE)
   GUICtrlSetState ($startbutton1, $GUI_SHOW)
   GUICtrlSetState ($startbutton1, $GUI_ENABLE)
   GUICtrlSetState ($statuscheck1, $GUI_ENABLE)
   GUICtrlSetState ($statuscheck2, $GUI_ENABLE)
   GUICtrlSetState ($statuscheck3, $GUI_ENABLE)
   GUICtrlSetState ($statuscheck4, $GUI_ENABLE)
   GUICtrlSetState ($processorinput, $GUI_ENABLE)
   GUICtrlSetState ($machineinput, $GUI_ENABLE)
   GUICtrlSetData($progressbar1, 0)
EndFunc

Func CLOSEClicked()
  Exit
  LogWrite()
EndFunc

While 1
   Sleep(1000)
WEnd


Описание:
При работе скрипта запускается функция StartOperation(), которая проверяет тип процессора, затем запускает нужные консольные приложения, которые скрипт перехватывает и выводит содержимое в Edit ($log). При нажатии кнопки $cancelbutton1 происходит вызов функции CancelOperation(), которая устанавливает значение переменной $stop, на которую в условия цикла дано задание If @error or $stop = True Then ExitLoop. При первой остановке цикл завершается корректно, однако при повторном запуске скрипта (Вызов функции StartOperation() кнопкой) остановка не происходит и скрипт не реагирует на действия, пока не завершится цикл.
 

gloss

Ленивое кодило
Сообщения
155
Репутация
5
Самая простая(на мой взгляд) старт/стоп функция.
Поэкспериментируйте с ней :smile:
Код:
Global $Paused
Func TogglePause()
	$Paused = Not $Paused
	While $Paused
		Sleep(100)
	WEnd
EndFunc
 

InnI

AutoIT Гуру
Сообщения
4,950
Репутация
1,445
Dr.Freezer [?]
скрипт уже ни на что не реагирует, пока не закончится цикл
Дело в том, что для событий GUISetOnEvent тоже есть внутренняя очередь. Если вы нажали кнопку, которая вызвала функцию StartOperation, то никакое другое событие не будет обработано, пока не завершится функция StartOperation. Вам нужно организовать работу таким образом, чтобы StartOperation сама вызывала какую-то функцию и завершала работу. Тогда будет возможность обработать сообщения от других элементов. Т.е. событие GUISetOnEvent может прервать внутреннюю функцию, только, если эта функция не вызвана другим событием GUISetOnEvent. Подробно с примерами всё это расписано здесь: Interrupting a running function
 
Автор
D

Dr.Freezer

Новичок
Сообщения
7
Репутация
0
InnI
Благодарю, что объяснили про очереди, почитал примеры, адаптировал под свой код, работает.
gloss
До вашего примера не дошел, но спасибо за уделенное время.

Всем спасибо.
OffTopic:

Как изменить репутацию - не нашел, видимо не доступно еще.
 
Верх