Как остановить скрипт при закрытии терминала, чтобы при последующем запуске терминала он вы в состоянии "не запущен"?
Метод автогена с провокацией ошибки исполнения считаю недостойным для Программного Комплекса QUIK )))
Пасхалочка для Алексея Иванникова:
Пользователь
Сообщений: Регистрация: 20.05.2015
12.11.2019 23:10:35
Костыли не рассматриваются? я первой строкой скрипта пишу
Код
if (isConnected() ~= 1) then return end
жгучий костыль, конечно, но скрипт сразу же вываливается при запуске.
Пользователь
Сообщений: Регистрация: 30.01.2015
13.11.2019 09:11:22
Это чересчур)) "на такое я пайтить не могу.. "
Пасхалочка для Алексея Иванникова:
Пользователь
Сообщений: Регистрация: 20.05.2015
13.11.2019 10:27:42
На сколько я понимаю, ТС мягко намекает, что коллбэк OnStop(flag = 2) не выполняет взятых на себя обязательств по предоставлении некоторой задержки на завершение потока main. как это обещано в документации?
Пользователь
Сообщений: Регистрация: 21.08.2015
13.11.2019 18:51:53
Занятный вопрос-то получился. Лобовое решение - если у скрипта есть файл настроек, иметь в нем флажок "не запускать". Перед выходом флажок устанавливать. При старте проверять, если стоит - сразу на выход (тут у мну спрашивали, зачем колбеки переопределять по ходу дела, вот за этим можно в том числе, если флажок стоит - меняем как минимум OnInit и main на пустые заглушки). Но тогда получается билет в одну сторону, скрипт не запустится больше никогда, пока внешним вмешательством флажок не сбросят. То есть чуть сложнее - если флажок стоит, _сбрасываем_его_ и на выход. При следующем запуске (с кнопки) все будет ок.
Пользователь
Сообщений: Регистрация: 30.01.2015
13.11.2019 18:54:16
Ув. разработчики!
Как нужно изменить скрипт
Код
local stopped,f
function main()
f = io.open("\\\\Server\\E\\1.log","w")
repeat
f:write("****\n")
sleep(16)
until stopped
f:close()
end
function OnStop(flag)
f:write(tostring(flag) .. "\n")
stopped = true
end
чтобы скрипт завершался при выключении терминала? У меня не получилось никакими ухищрениями.
Благодарю.
Пасхалочка для Алексея Иванникова:
Пользователь
Сообщений: Регистрация: 20.05.2015
13.11.2019 19:00:53
Это тоже костыль. мой тогда даже проще и безобиднее. ТС хочет, чтобы при перезапуске КВИКа скрипт вообще никак "не трогался". От слова совсем. Словно он отработал и вышел вот прям-прям перед закрытием терминала.
По идее это должно реализоваться через коллбэк OnStop(flag). Флагустаналивается == 2 при закрытии терминала. По идее надо поставить переменную, отвечающую за "вечный" цикл в потоке main в состояние false, и просто дождаться когда произойдет выход из этого "вечного" циклаи завершится скрипт. тогда он автоматом запускаться не будет. Только руками. Но проблема в том, что терминалу нет никакого дела до возвращённой коллбеком задержки, хотя документация нам ее всячески обещает. Так что терминал просто сохраняет состояние скрипта как "работающий" и запускает его при следующем запуске. Возможно я ошибаюсь, разумеется.
Пользователь
Сообщений: Регистрация: 21.08.2015
13.11.2019 19:07:57
Цитата
Алексей Дуванов написал: Но проблема в том, что терминалу нет никакого дела до возвращённой коллбеком задержки, хотя документация нам ее всячески обещает.
Не согласен, терминал уважает возвращенное значение, сам использую. При описанном раскладе автостарт скриптов вообще бы не работал, бо ВСЕ скрипты завершаются таким образом, независимо от задержки. Раз уж терминал начал закрываться, он, похоже, сначала сохраняет информацию о том, какие скрипты запущены, и только потом им сигналит о выходе. Следовательно, напрашивается еще более ужасный костыль с прямой правкой scripts.dat ) Ну или новая функция "отключить мой автостарт", которую можно было бы дернуть перед выходом.
Пользователь
Сообщений: Регистрация: 21.08.2015
13.11.2019 19:33:09
Цитата
Anton написал: или новая функция "отключить мой автостарт"
Но есть решение и покрасивше (как мне кажется), малость поменять OnStop следующим образом
1) не возвращено ничего - все работает как и сейчас
2) возвращен только таймаут - все работает как и сейчас
3) возвращены таймаут и true - скрипт записывается в автозапуск (даже если завершается не в результате закрытия терминала)
4) возвращены таймаут и false - скрипт удаляется из автозапуска (даже если завершается в результате закрытия терминала)
Тогда появляется и смысл в аргументе этой функции, т.к. сейчас от него проку не наблюдается.
Пользователь
Сообщений: Регистрация: 20.05.2015
13.11.2019 19:40:53
Проделал несколько экспериментов. У меня почему то при закрытии терминала приходит только коллбэк OnClose(). Коллбэк OnStop(flag) только, если завершаешь скрипт руками. То есть вообще не приходит. Проверял, записывая в лог на диск.
Пользователь
Сообщений: Регистрация: 21.08.2015
13.11.2019 19:52:58
Цитата
Алексей Дуванов написал: Проделал несколько экспериментов. У меня почему то при закрытии терминала приходит только коллбэк OnClose(). Коллбэк OnStop(flag) только, если завершаешь скрипт руками. То есть вообще не приходит. Проверял, записывая в лог на диск.
Странно, проверил сейчас, все приходит.
Код
local stop_state = 0
local log_file = io.open(getScriptPath() .. "\\stoplog.txt", "w")
main = function()
while 0 == stop_state do
sleep(1000)
end
log_file:write("Exit main with code " .. stop_state .. "\n")
end
OnS top = function(flag)
log_file:write("OnStop with code " .. flag .. "\n")
stop_state = flag
return 15000
end
Пользователь
Сообщений: Регистрация: 20.05.2015
13.11.2019 19:59:05
да. у меня тоже приходит. соврал. а при закрытии терминала он 15 секунд ждёт? (я просто в "неродной" системе работаю - wine)
Пользователь
Сообщений: Регистрация: 20.05.2015
13.11.2019 20:06:25
Всё. Сдаюсь. Честно ждёт. И всё равно перезапускает. Подождем, что ответят разработчики. Даже интересно стало
Пользователь
Сообщений: Регистрация: 21.08.2015
13.11.2019 20:12:16
Цитата
Алексей Дуванов написал: а при закрытии терминала он 15 секунд ждёт?
Неа, дохнет мгновенно и даже лог сфлашить не успевает. По ощущениям его грохают путем прибития машины луа без какой бы то ни было очистки. То есть, выходит, выше я наврал, таймаут уважают только при остановке с кнопки, да и то выжидают тупым WaitFor с таймаутом, юай виснет на время таймаута => сообщения не обрабатываются.
Ссорри, поспешил, это окно квика прячется мгновенно, а скрипт таки дорабатывает, да.
Пользователь
Сообщений: Регистрация: 21.08.2015
13.11.2019 20:20:17
Плюс интересное наблюдение. Окно квика прячется, скрипт держит info.exe в диспетчере задач, потом он завершается и сразу выскакивает dllhost на несколько секунд. То же самое после старта квика, выскакивает dllhost и пропадает. Вопрос - а чо это он делает такое, что нельзя было из квика сделать?
Пользователь
Сообщений: Регистрация: 21.08.2015
13.11.2019 20:41:41
Уточним наблюдения, dllhost выскакивает всякий раз при запуске скрипта кнопкой, после остановки скрипта кнопкой, после запуска квика при наличии автозапускаемых скриптов, после завершения квика с работающими скриптами. Не выскакивает при отсутствии работающих скриптов. Вывод - dllhost запускает и останавливает скрипты. Отсюда (возможно) рукой подать до некой широкой автоматизации их запуска и остановки, нужно только разобраться, что он там дергает и как.
Пользователь
Сообщений: Регистрация: 20.05.2015
13.11.2019 22:19:51
Да. У меня в линуксе под вайном абсолютно такое же поведение (в htop смотрел). Очень хотелось бы ответ на первоначальный вопрос от разработчиков получить.
Пользователь
Сообщений: Регистрация: 21.08.2015
14.11.2019 00:10:19
В общем, потрейсил я, зачем квиком дергается dllhost. Судя по всему, квик подписывается на уведомления об изменении файла скрипта, и вот это и приводит к вызовам dllhost'а, ну плюс там еще несколько вызовов ради каких-то иконок из кэша. Можно просто поменять файл скрипта при открытом квике, сохранить и увидеть, как опять выскочил dllhost. При запуске и остановке, соответственно, дергается подписка/отписка. Уот так уот все прозаично.
Пользователь
Сообщений: Регистрация: 21.08.2015
14.11.2019 02:09:21
Еще одно ткскть исследование, теперь на предмет scripts.dat. Формат у него такой (си-подобный псевдокод)
Код
#pragma pack(push, 1)
// NOTE: no any padding between fields
struct scripts_dat_header_t
{
char magic[8]; // = "INFOSCRT"
int unknown1; // = 1 (?)
int unknown2; // = 1 (?)
int nrecords; // = (probably the number of subsequent records)
};
struct scripts_dat_record_t
{
int script_path_length; // the length of the subsequent string
char script_full_path[1]; // variable length array; the full path to the script file; not zero-terminated
int autorun_enabled; // 1 if autorun enabled, else 0
};
struct scripts_dat_t
{
struct scripts_dat_header_t header;
struct scripts_dat_record_t records[1]; // variable length array
};
#pragma pack(pop)
Но использовать его из скрипта без суровых костылей все равно не получится, т.к. квик записывает этот файл ПОСЛЕ того, как наш скрипт уже прибит. То есть (попробовал) наши самостийные изменения будут им перезаписаны. Так что и тут голяк, господа.
Пользователь
Сообщений: Регистрация: 23.01.2015
14.11.2019 12:16:38
s_mike@rambler.ru, Михаил, Можно запоминать состояние stopped во внешнем хранилище. Или добавить проверку на что то еще, например подключение к серверу.
Пользователь
Сообщений: Регистрация: 30.01.2015
14.11.2019 12:29:47
Цитата
Sergey Gorokhov написал: , Михаил, Можно запоминать состояние stopped во внешнем хранилище. Или добавить проверку на что то еще, например подключение к серверу.
А (правильный) вариант исправления/добавления терминала уже не рассматривается в принципе? Базовая потребность - и только костылями?
Пасхалочка для Алексея Иванникова:
Пользователь
Сообщений: Регистрация: 23.01.2015
14.11.2019 12:34:05
Цитата
s_mike@rambler.ru написал: А (правильный) вариант исправления/добавления терминала уже не рассматривается в принципе? Базовая потребность - и только костылями?
Если речь о том чтобы зарегистрировать пожелание, тогда Вы должны его озвучить (пожелание)
написал: А (правильный) вариант исправления/добавления терминала уже не рассматривается в принципе? Базовая потребность - и только костылями?
Если речь о том чтобы зарегистрировать пожелание, тогда Вы должны его озвучить (пожелание)
Сергей, у меня нет коммерческих отношений с вашей компанией, я ничего ей не должен. Извините.
Пасхалочка для Алексея Иванникова:
Пользователь
Сообщений: Регистрация: 04.05.2018
03.12.2019 12:09:21
IsRun = true
function OnInit() end;
function main() while IsRun do if isConnected() == 0 then IsRun = false end sleep(100) end end
function OnStop() IsRun = false end
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
07.12.2019 11:48:29
Есть ещё вариант, но он вам не понравится:
Код
local stopped, id
function OnStop(flag)
stopped = true
DestroyTable(id)
end
function main()
id = AllocTable()
CreateWindow(id)
SetTableNotificationCallback(id, function(t_id, msg, par1, par2)
if msg == QTABLE_CLOSE then
OnStop()
end
end)
repeat
sleep(16)
until stopped
end
Надо делать так, как надо. А как не надо - делать не надо.
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
05.11.2020 14:29:46
Можно ещё в первой строке написать:
Код
if os.clock() < 5 then return end
Надо делать так, как надо. А как не надо - делать не надо.