Что нового

_ScriptRestart() - Надёжный перезапуск скрипта

snoitaleR

AutoIT Гуру
Сообщения
855
Репутация
223
Re: Перезапуск скрипта

Kaster
В ответе №2 они обсуждали то, что в твоем скрипте (ответ №7) не учитывается...
Вот я и задал вопрос... :smile:
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Re: Перезапуск скрипта

snoitaleR сказал(а):
В ответе №2 они обсуждали то, что в твоем скрипте (ответ №7) не учитывается...
прости, но в ответе №2 я не нашел ничего касаемо моего скрипта :-[


Добавлено:
Сообщение автоматически объединено:

Vovsla сказал(а):
а почему вы так неохотно пользуетесь дополнительными библиотеками?
чтобы не городить огород ;)
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Re: Перезапуск скрипта

snoitaleR [?]
для чего тогда Yashied и CreatoR таким "навороченным" способом пытались убедиться, что "родительский" скрипт завершил работу?
Например, если скрипт на выходе делает записи в файлы конфигурации, а при запуске читает их, так вот если запустить скрипт поновой в тот момент пока его первая копия запущена, то он считает старые параметры, а не те что пользователь мог сделать в первой копии запущенного скрипта (программы).

Vovsla [?]
не на выходе, если хотим выйти
Ясно. В любом случае это не так уж и важно как выполнить перезапуск, главное чтобы был надёжный метод, и он есть ;)

Мне вот вообще странно что вокруг этой темы развелось столько обсуждений, тема то супер тривиальная :whistle:.
 

snoitaleR

AutoIT Гуру
Сообщения
855
Репутация
223
Re: Перезапуск скрипта

CreatoR
У меня было много вопросов по этой теме... :-[
Когда речь заходит о надежности, у меня всегда много вопросов... :smile:
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Re: Перезапуск скрипта

И тут к нам на помощь приходит WinAPI. :smile: Вот еще один интересный способ для перезапуска скрипта. Не забываем качать библиотеку WinAPIEx.au3. Запускать нужно EXE-шник.


Код:
#Include <WinAPIEx.au3>

If MsgBox(36, 'Restarting...', 'Press OK to restart this script.') = 6 Then
	Run(@ScriptFullPath)
EndIf

Func OnAutoItStart()
	Global $hSemaphore = _WinAPI_CreateSemaphore('MySuperProject', 1, 1)
	_WinAPI_WaitForSingleObject($hSemaphore)
EndFunc   ;==>OnAutoItStart

Func OnAutoItExit()
	_WinAPI_ReleaseSemaphore($hSemaphore)
	_WinAPI_FreeHandle($hSemaphore)
EndFunc   ;==>OnAutoItExit



Добавлено:
Сообщение автоматически объединено:

Последние ответы перенес сюда.


Добавлено:
Сообщение автоматически объединено:

snoitaleR сказал(а):
А для чего тогда Yashied и CreatoR таким "навороченным" способом пытались убедиться, что "родительский" скрипт завершил работу?

Когда пишешь программу, то в большинстве случаев предотвращаешь двойной ее запуск. В самом простом случае это делается так:

Код:
_Singleton('MyProgram')


Так вот, в данном случае Run(@ScriptFullPath) работать не будет. Можешь сам попробывать. Для этого я и пытался дождаться завершения перезагружаемого скрипта.

Код:
#Include <Misc.au3>
#Include <WinAPIEx.au3>

_Singleton('MyProgram')

If MsgBox(36, 'Restarting...', 'Press OK to restart this script.') = 6 Then
	Run(@ScriptFullPath)
	Exit
EndIf



Добавлено:
Сообщение автоматически объединено:

[box title=Итог]Итак, подвожу итог. А итогом является библиотека Restart.au3, которую я написал, прочитав все, что вы здесь написали. Никаких VBS, BAT, CMD и даже WinAPI, тлько чистый AutoIt. Это самая простая из моих UDF-ок.

:smile:[/box]
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Re: Перезапуск скрипта

Yashied [?]
Никаких VBS, BAT, CMD и даже WinAPI, тлько чистый AutoIt.
Тот же пример с vbs, но так сказать на чистом AutoIt'е :smile:

Код:
If MsgBox(36, 'Restarting...', 'Press OK to restart this script.') = 6 Then
	_ScriptRestart()
EndIf

Func _ScriptRestart()
	Local $sAutoIt_File = @TempDir & "\~Au3_ScriptRestart_TempFile.au3"
	Local $sRunLine, $sScript_Content, $hFile
	
	$sRunLine = @ScriptFullPath
	If Not @Compiled Then $sRunLine = @AutoItExe & ' /AutoIt3ExecuteScript ""' & $sRunLine & '""'
	If $CmdLine[0] > 0 Then $sRunLine &= ' ' & $CmdLineRaw
	
	$sScript_Content &= '#NoTrayIcon' & @CRLF
	$sScript_Content &= 'While ProcessExists(' & @AutoItPID & ')' & @CRLF
	$sScript_Content &= '	Sleep(10)' & @CRLF
	$sScript_Content &= 'WEnd' & @CRLF
	$sScript_Content &= 'Run("' & $sRunLine & '")' & @CRLF
	$sScript_Content &= 'FileDelete(@ScriptFullPath)' & @CRLF
	
	$hFile = FileOpen($sAutoIt_File, 2)
	FileWrite($hFile, $sScript_Content)
	FileClose($hFile)
	
	Run(@AutoItExe & ' /AutoIt3ExecuteScript "' & $sAutoIt_File & '"', @ScriptDir, @SW_HIDE)
	Sleep(1000)
	Exit
EndFunc
 

vovsla

Осваивающий
Сообщения
607
Репутация
36
Re: _ScriptRestart - Надёжный перезапуск скрипта

итог в ответе 24 не приемлем как библиотека, т.к. в Restart.au3 содержится функция OnAutoItStart() , это делает невозможным использование Restart.au3 как библиотеки когда OnAutoItStart() используется в основном скрипте по причине дублирования названия функций. Из такого решения можно только копировать функции в основной скрипт
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Re: _ScriptRestart - Надёжный перезапуск скрипта

Vovsla сказал(а):
итог в ответе 24 не приемлем как библиотека, т.к. в Restart.au3 содержится функция OnAutoItStart() , это делает невозможным использование Restart.au3 как библиотеки когда OnAutoItStart() используется в основном скрипте по причине дублирования названия функций. Из такого решения можно только копировать функции в основной скрипт

А ты часто используешь OnAutoItStart()? В любом случае в Beta ты можешь регистрировать сколько угодно собственных OnAutoItStart() функций (см. #OnAutoItStartRegister).

Также можно переименовать OnAutoItStart() из Restart.au3 в, например, _OnAutoItStart() и вызвать ее из собственной функции. Я не вижу здесь серьезных проблем.
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Re: Перезапуск скрипта

Kaster сказал(а):
...не важно запущены ли два экземпляра одного и того же скрипта одновременно, т.к. "родительский" после того как запустил "дочерний" неминуемо закроется, не ожидая каких-либо действий со стороны интерпретатора или "дочернего" процесса.

Нужно еще учитывать, что программа может иметь защиту от повторного запуска, например _Singleton(). В этом случае программа повторно просто не запустится, необходимо сначала выгрузить первую копию, а затем уже запускать снова.
 

SyDr

Сидра
Сообщения
651
Репутация
158
Хм... Ребята, а если:
1) Скрипт перезапуска должен быть написан на AutoIt (vbs может быть отключён) или bat-файлах
2) Скомпилированный скрипт может иметь директву #NoAutoIt3Execute
Что делать в этом случае? Хотелось бы, чтобы именно на AutoIt было.
 

kzru_hunter

Осваивающий
Сообщения
144
Репутация
49
Yashied Хороший способ :smile:
Процессор не грузит в отличие от способа с пингом и точную задержку можно поставить.
Но вот есть вопрос: сработает ли этот скрипт на любой "чистой" операционной системе без всяких дополнительных компонент, начиная с 2000? я просто в объектах не разбираюсь
 
Автор
Yashied

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Лучше использовать этот способ. Проще уже некуда.
 

kzru_hunter

Осваивающий
Сообщения
144
Репутация
49
Используя тот способ, скрипт всё равно находится в процессах. А нужен такой способ, чтобы скрипт не был в процессах, пока происходит его перезапуск, чтобы за время, пока он перезапускается можно было подменить exe либо сделать какие-нибудь другие действия над ним.
Лучшего способа, чем этот, пока не видел.
Уже были проблемы с объектами, поэтому и спросил.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
kzru_hunter
Попробуйте так, только в скомпилированном виде:
Код:
#include <File.au3>
OnAutoItExitRegister("_ScriptReStart")
MsgBox(0, "Перезапуск", "После закрытия через ~10 секунд скрипт опять запуститься")

Func _ScriptReStart()
	$sTemp = _TempFile(@TempDir, '~', '.bat')
	$sPath = FileGetShortName(@ScriptFullPath)
	$hFile = FileOpen($sTemp, 2)
	FileWriteLine($hFile, '@echo off')
	FileWriteLine($hFile, 'ping -n 10 127.0.0.1 > nul')
	FileWriteLine($hFile, 'Start ' & $sPath)
	FileWriteLine($hFile, 'Del /F /Q %0')
	FileClose($hFile)
	Run($sTemp, '', @SW_HIDE)
EndFunc   ;==>_ScriptReStart
 

Yuri

AutoIT Гуру
Сообщения
737
Репутация
282
Новичек - я.
Вот такое решение:
Два скрипта пишем (далее они - EXE)
Первый - загрузчик основной, запускает Второго и постоянно висит в процессах и мониторит его.
Второй - та самая программа, которая подлежит мониторингу.
Как только Первый увидел, что Второй ушел из процесса, - запускает Второго.
Первому надо уделить особое внимание - чтоб жил всегда, пока сама ОС жива.
Вот и все.
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
kzru_hunter [?]
А нужен такой способ, чтобы скрипт не был в процессах,
Так перезапустит только, если скрипта (скомпилированного) нет в процессах
Код:
#include <File.au3>

If MsgBox(266276, "Перезапуск", "После закрытия через ~10 секунд" & @CRLF & "скрипт можно перезапустить." & _
		@CRLF & @CRLF & "Перезапустить?") = 6 Then _ScriptReStart()

Func _ScriptReStart()
	$sTemp = _TempFile(@TempDir, '~', '.bat')
	$sPath = FileGetShortName(@ScriptFullPath)
	$hFile = FileOpen($sTemp, 2)
	FileWriteLine($hFile, '@echo off')
	FileWriteLine($hFile, 'chcp 1251 > nul')
	FileWriteLine($hFile, ':Again')
	FileWriteLine($hFile, 'tasklist /FI "IMAGENAME eq ' & @ScriptName & '"| find "' & @AutoItPID & '"')
	FileWriteLine($hFile, 'If %ErrorLevel%==0 GoTo Again')
	FileWriteLine($hFile, 'ping -n 10 127.0.0.1 > nul')
	FileWriteLine($hFile, 'Start ' & $sPath)
	FileWriteLine($hFile, 'Del /F /Q %0')
	FileClose($hFile)
	Run($sTemp, '', @SW_HIDE)
EndFunc   ;==>_ScriptReStart
 

art279

Новичок
Сообщения
20
Репутация
3
Как я понял все тут обсуждают методы надёжного перезапуска скрипта после завершения его работы?! Если да то вот мой вариант демонстрации перезапуска скрипта:


Код:
MsgBox(64, "Info", "TEST", 5)
$dist=(@ScriptFullPath)
Run($dist)
 

art279

Новичок
Сообщения
20
Репутация
3
Garrett сказал(а):
art279 [?]
перезапуска скрипта после завершения его работы?!
А так?! ;)
Код:
MsgBox(64, "Info", "TEST", 5)
Exit
$dist=(@ScriptFullPath)
Run($dist)


Этот код должен стоять перед Exit в противном случае скрипт просто не успевает себя запустить:
Код:
$dist=(@ScriptFullPath)
Run($dist)


При этом процесс не "задваивается", можете сами в этом убедится, запустите диспетчер задач или его аналог....
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
art279 Я же вас цитировал!!! Тут ключевое слово:
...методы надёжного перезапуска скрипта после завершения его работы...
А где в вашем коде завершение работы скрипта?!
 
Верх