На сколько я понимаю, ТС мягко намекает, что коллбэк OnStop(flag = 2) не выполняет взятых на себя обязательств по предоставлении некоторой задержки на завершение потока main. как это обещано в документации?
Занятный вопрос-то получился. Лобовое решение - если у скрипта есть файл настроек, иметь в нем флажок "не запускать". Перед выходом флажок устанавливать. При старте проверять, если стоит - сразу на выход (тут у мну спрашивали, зачем колбеки переопределять по ходу дела, вот за этим можно в том числе, если флажок стоит - меняем как минимум OnInit и main на пустые заглушки). Но тогда получается билет в одну сторону, скрипт не запустится больше никогда, пока внешним вмешательством флажок не сбросят. То есть чуть сложнее - если флажок стоит, _сбрасываем_его_ и на выход. При следующем запуске (с кнопки) все будет ок.
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
чтобы скрипт завершался при выключении терминала? У меня не получилось никакими ухищрениями.
Это тоже костыль. мой тогда даже проще и безобиднее. ТС хочет, чтобы при перезапуске КВИКа скрипт вообще никак "не трогался". От слова совсем. Словно он отработал и вышел вот прям-прям перед закрытием терминала.
По идее это должно реализоваться через коллбэк OnStop(flag). Флагустаналивается == 2 при закрытии терминала. По идее надо поставить переменную, отвечающую за "вечный" цикл в потоке main в состояние false, и просто дождаться когда произойдет выход из этого "вечного" циклаи завершится скрипт. тогда он автоматом запускаться не будет. Только руками. Но проблема в том, что терминалу нет никакого дела до возвращённой коллбеком задержки, хотя документация нам ее всячески обещает. Так что терминал просто сохраняет состояние скрипта как "работающий" и запускает его при следующем запуске. Возможно я ошибаюсь, разумеется.
Алексей Дуванов написал: Но проблема в том, что терминалу нет никакого дела до возвращённой коллбеком задержки, хотя документация нам ее всячески обещает.
Не согласен, терминал уважает возвращенное значение, сам использую. При описанном раскладе автостарт скриптов вообще бы не работал, бо ВСЕ скрипты завершаются таким образом, независимо от задержки. Раз уж терминал начал закрываться, он, похоже, сначала сохраняет информацию о том, какие скрипты запущены, и только потом им сигналит о выходе. Следовательно, напрашивается еще более ужасный костыль с прямой правкой scripts.dat ) Ну или новая функция "отключить мой автостарт", которую можно было бы дернуть перед выходом.
Проделал несколько экспериментов. У меня почему то при закрытии терминала приходит только коллбэк OnClose(). Коллбэк OnStop(flag) только, если завершаешь скрипт руками. То есть вообще не приходит. Проверял, записывая в лог на диск.
Алексей Дуванов написал: Проделал несколько экспериментов. У меня почему то при закрытии терминала приходит только коллбэк 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
Алексей Дуванов написал: а при закрытии терминала он 15 секунд ждёт?
Неа, дохнет мгновенно и даже лог сфлашить не успевает. По ощущениям его грохают путем прибития машины луа без какой бы то ни было очистки. То есть, выходит, выше я наврал, таймаут уважают только при остановке с кнопки, да и то выжидают тупым WaitFor с таймаутом, юай виснет на время таймаута => сообщения не обрабатываются.
Плюс интересное наблюдение. Окно квика прячется, скрипт держит info.exe в диспетчере задач, потом он завершается и сразу выскакивает dllhost на несколько секунд. То же самое после старта квика, выскакивает dllhost и пропадает. Вопрос - а чо это он делает такое, что нельзя было из квика сделать?
Уточним наблюдения, dllhost выскакивает всякий раз при запуске скрипта кнопкой, после остановки скрипта кнопкой, после запуска квика при наличии автозапускаемых скриптов, после завершения квика с работающими скриптами. Не выскакивает при отсутствии работающих скриптов. Вывод - dllhost запускает и останавливает скрипты. Отсюда (возможно) рукой подать до некой широкой автоматизации их запуска и остановки, нужно только разобраться, что он там дергает и как.
Да. У меня в линуксе под вайном абсолютно такое же поведение (в htop смотрел). Очень хотелось бы ответ на первоначальный вопрос от разработчиков получить.
В общем, потрейсил я, зачем квиком дергается dllhost. Судя по всему, квик подписывается на уведомления об изменении файла скрипта, и вот это и приводит к вызовам dllhost'а, ну плюс там еще несколько вызовов ради каких-то иконок из кэша. Можно просто поменять файл скрипта при открытом квике, сохранить и увидеть, как опять выскочил dllhost. При запуске и остановке, соответственно, дергается подписка/отписка. Уот так уот все прозаично.
Еще одно ткскть исследование, теперь на предмет 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)
Но использовать его из скрипта без суровых костылей все равно не получится, т.к. квик записывает этот файл ПОСЛЕ того, как наш скрипт уже прибит. То есть (попробовал) наши самостийные изменения будут им перезаписаны. Так что и тут голяк, господа.
s_mike@rambler.ru, Михаил, Можно запоминать состояние stopped во внешнем хранилище. Или добавить проверку на что то еще, например подключение к серверу.
Sergey Gorokhov написал: s_mike@rambler.ru, Михаил, Можно запоминать состояние stopped во внешнем хранилище. Или добавить проверку на что то еще, например подключение к серверу.
А (правильный) вариант исправления/добавления терминала уже не рассматривается в принципе? Базовая потребность - и только костылями?
s_mike@rambler.ru написал: А (правильный) вариант исправления/добавления терминала уже не рассматривается в принципе? Базовая потребность - и только костылями?
Если речь о том чтобы зарегистрировать пожелание, тогда Вы должны его озвучить (пожелание)
s_mike@rambler.ru написал: А (правильный) вариант исправления/добавления терминала уже не рассматривается в принципе? Базовая потребность - и только костылями?
Если речь о том чтобы зарегистрировать пожелание, тогда Вы должны его озвучить (пожелание)
Сергей, у меня нет коммерческих отношений с вашей компанией, я ничего ей не должен. Извините.
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
Надо делать так, как надо. А как не надо - делать не надо.