Что нового

Перезапуск программы по условию

alex_tm

Новичок
Сообщения
16
Репутация
0
Добрый день.
Есть работающий скрипт, который ранее работал без проблем с нужной мне программой (условный process.exe).
Скрипт не мой - добрые люди подсказали.
Код:
if WinExists ("Внимание") Then
      WinActivate("Внимание")
      send ("{right}")
      send ("{enter}")
      Sleep (10000)
      Run("C:\process.exe")
      Exit
Else
   Exit
EndIf
Суть такова: process.exe периодически (хаотично, безсистемно) показывает окно с заголовком "Внимание" и с кнопками "да" и "нет".
Когда такое окно появляется, делается переход вправо на кнопку "нет" и подтверждается, после чего программа process.exe закрывается.
Процесс закрытия не быстрый, поэтому установил небольшой sleep чтобы процесс успел выгрузиться, после которого снова запускаю process.exe.
В планировщике каждые 5 минут скомпилированный скрипт запускается, и если не находит окна с заголовком "Внимание" - выгружается, а если находит такое окно - перезагружает программу, и тоже выгружается. И так каждые 5 минут. Если программа не работает 5 минут - для меня не критично, а вот если она долго не работает - это уже проблема. Таким образом нужный мне функционал с помощью этого скрипта организован и полностью меня устраивает.
Но с какого-то момента - после очередного обновления программы (она стала более прожорливой) - выгрузка процесса из памяти стала затягиваться. Причём иногда она может закрыться за 10 секунд, а иногда ей и минуты мало, а то и вовсе не выгружается из памяти - помогает только завершение процесс в диспетчере задач. В этом случае, ни один sleep не поможет.
Поэтому, я думаю правильней было бы сделать несколько циклов проверки (к примеру, 5 циклов с 20-секундными паузами между ними) присутствия в памяти процесса, после окончания которых считать такой процесс зависшим. После чего убить этот процесс и снова запустить Run("C:\process.exe").
Как организовать такую проверку в несколько циклов, чтобы в каждом цикле - если процесс ещё в памяти, перейти после ожидания к следующему циклу проверки, а если процесс уже выгрузился - завершить все циклы и сразу перейти к Run("C:\process.exe"). Но если и после 5 циклов процесс всё ещё не выгрузился - сделать ProcessClose и перейти к Run("C:\process.exe")?
Спасибо.
 
Последнее редактирование:

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Код:
If WinExists("Внимание") Then
    WinActivate("Внимание")
    WinWaitActive("Внимание")
    Send("{right}")
    Send("{enter}")
    
    If Not ProcessWaitClose('process.exe', 5) Then ;5 seconds
        ProcessClose('process.exe')
    EndIf
    
    Run("C:\process.exe")
EndIf
 
Автор
A

alex_tm

Новичок
Сообщения
16
Репутация
0
Код:
If WinExists("Внимание") Then
    WinActivate("Внимание")
    WinWaitActive("Внимание")
    Send("{right}")
    Send("{enter}")
 
    If Not ProcessWaitClose('process.exe', 5) Then ;5 seconds
        ProcessClose('process.exe')
    EndIf
 
    Run("C:\process.exe")
EndIf
Я не силён в этом настолько же, насколько и Вы, поэтому на данном этапе - Вы бы не могли описать значение каждой строки кода, чтобы понять что она делает? Если не трудно.
Интересует конкретно эта часть:
Код:
If Not ProcessWaitClose('process.exe', 5) Then ;5 seconds
        ProcessClose('process.exe')
    EndIf
    Run("C:\process.exe")
EndIf
Просто я не понял, каким образом скрипт не найдя окна с заголовком "Внимание" завершит работу и закроет скомпилированный скрипт, а так же - каким образом реализована 5-кратная проверка на предмет отсутствия процесса?
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Вы бы не могли описать значение каждой строки кода
Код:
If WinExists("Внимание") Then ;Если окно с названием "Внимание" существует то...
    WinActivate("Внимание") ;Активируем окно
    WinWaitActive("Внимание") ;Ждём пока оно в действительности станет активным
    Send("{right}") ;Отправляем нажатие стрелки ВПРАВО
    Send("{enter}") ;Отправляем нажатие кнопки ENTER
   
    If Not ProcessWaitClose('process.exe', 5) Then ;Ожидаем закрытия процесса в течении 5-ти секунд, если не закрылся то...
        ProcessClose('process.exe') ;Убиваем процесс
    EndIf
   
    Run("C:\process.exe") ;Запускаем процесс снова
EndIf


каким образом реализована 5-кратная проверка на предмет отсутствия процесса?
В данном коде никаким, а оно нужно? из логики задачи я сделал вывод что достаточно просто ожидать успешное (или нет) закрытие процесса после нажатия на кнопку в окне.
 
Автор
A

alex_tm

Новичок
Сообщения
16
Репутация
0
Код:
If WinExists("Внимание") Then ;Если окно с названием "Внимание" существует то...
    WinActivate("Внимание") ;Активируем окно
    WinWaitActive("Внимание") ;Ждём пока оно в действительности станет активным
    Send("{right}") ;Отправляем нажатие стрелки ВПРАВО
    Send("{enter}") ;Отправляем нажатие кнопки ENTER
 
    If Not ProcessWaitClose('process.exe', 5) Then ;Ожидаем закрытия процесса в течении 5-ти секунд, если не закрылся то...
        ProcessClose('process.exe') ;Убиваем процесс
    EndIf
 
    Run("C:\process.exe") ;Запускаем процесс снова
EndIf



В данном коде никаким, а оно нужно? из логики задачи я сделал вывод что достаточно просто ожидать успешное (или нет) закрытие процесса после нажатия на кнопку в окне.
Не совсем так - проблема именно в том, что процесс чаще всего закрывается, но иногда это происходит быстро, а иногда и более минуты-двух. Полное зависание - когда остаётся только убивать процесс через диспетчер задач - это редкие случаи.
Именно поэтому мне нужны несколько циклов проверки, к примеру по 1 минуте или по 20 секунд (не принципиально, сам потом определю эту задержку), - есть в памяти процесс или нет. Мне предпочтительнее дождаться самостоятельной выгрузки программы из памяти, нежели её безусловное убийство, т.к. в большинстве случаев она сама выгружается. И как только она выгрузится - тут же запустить её снова.
Поэтому я и решил для себя так - первая проверка через 20 секунд - есть процесс или нет. Если есть - ждём ещё 20 секунд. Снова проверяем - есть процесс или нет. Если нет - загружаем Run("C:\process.exe"), если есть - снова ждём 20 секунд, и т.д. Т.е. таким образом я даю программе время выгрузиться, и тут же загрузиться снова.
Основная задача не убить процесс, а дать ему время самому выгрузиться, и только после того как будет пройден какой-то предел допустимого для зависшего состояния времени - к примеру 5 минут если 5шт 1-минутных циклов, или 100 секунд, если 5шт 20-секундных циклов - только тогда её безусловно убить.
Второй выигрыш от этой циклической проверки программы в том, что я сделаю минимальную задержку между закрытием программы по нажатию на кнопку "нет" и запуском её новой копии. Поясню. Допустим, циклы по 20 секунд. Программа сама выгрузилась за 30 секунд. Т.е. прошел первый 20-секундный цикл, в котором процесс ещё был в памяти. А по окончанию второго 20-секундного цикла - программы уже в памяти нет. Всё - значит можно запускать Run("C:\process.exe") . Что имеем в итоге - через 40 секунд после нажатия на кнопку "нет" получаем вновь запущенную программу. И далее по аналогии - если программа выгрузится из памяти на 46 секунде, то по окончанию третьего 20-секундного цикла проверки (т.е. на 60 секунде) я получу вновь запущенную программу.
 
Последнее редактирование:

IMStrelcov

CTPEJIbLLOB
Сообщения
253
Репутация
64
Я бы посоветовал мониторить загруженность процессора этой программой, а так же запись и чтение на диск этой программой, если прога не пишет, не читает и не ест процессор - значит она зависла и ее нужно убить. В противном случае ожидать пока она выгрузится.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
проблема именно в том, что процесс чаще всего закрывается, но иногда это происходит быстро, а иногда и более минуты-двух
Ты же сам писал, что нужно 5 циклов по минуте, какая разница, будет это 5 циклов, или одно ожидание в 5 минут, когда процесс завершиться в этом промежутке, скрипт перейдёт к запуску процесса.
Нужно понимать как работает ProcessWaitClose, она завершит своё ожидание как только процесс выгрузится.
Просто я показал на примере в 5 секунд, можно и 5 минут:
Код:
If Not ProcessWaitClose('process.exe', 5 * 60) Then

В этом случае на любом этапе времени, процесс запустится (если был самостоятельно завершён), либо по истечению 5-ти минут будет закрыт и также запустится.
 
Автор
A

alex_tm

Новичок
Сообщения
16
Репутация
0
Ты же сам писал, что нужно 5 циклов по минуте, какая разница, будет это 5 циклов, или одно ожидание в 5 минут, когда процесс завершиться в этом промежутке, скрипт перейдёт к запуску процесса.
Нужно понимать как работает ProcessWaitClose, она завершит своё ожидание как только процесс выгрузится.
Просто я показал на примере в 5 секунд, можно и 5 минут:
Код:
If Not ProcessWaitClose('process.exe', 5 * 60) Then

В этом случае на любом этапе времени, процесс запустится (если был самостоятельно завершён), либо по истечению 5-ти минут будет закрыт и также запустится.
Вы правы - я не совсем правильно понимал как работает ProcessWaitClose.
Вы действительно помогли мне, и это подтвердилось на практике - уже проверил в реальных условиях.
Спасибо!
 
Верх