Форум » [x]Harbour » Как запретить перезагрузку Windows из Harbour ? » Ответить

Как запретить перезагрузку Windows из Harbour ?

Sergy: Добрый день. Многие сталкивались, наверное, с ситуацией, когда при перезагрузке Windows (например, после установки очередных обновлений) возникает сообщение: "Windows не может завершить работу приложения ABCDEF, нажмите "Завершить" или "Отменить". Как добиться похожего поведения программы на Harbour? Понятно, что этот механизм спрятан где-то внутри системы. Думаю, было-бы достаточно, чтобы при получении сообщения от операционки "быстро выходить" выполнялась определенная функция: закрывались таблицы, сохранялись документы и тп... Как считаете, это реально ? PS: откуда все это взялось: в процессе поиска редких и "необъяснимых" вылетов без единого сообщения в моем приложении прошло какое-то "кривое" октябрьское обновление для WinXP, которое требует многократной перезагрузки компа. Я сижу и смотрю логи, пытаюсь понять, что привело к вылетам и пустым логам... Спрашиваю у сотрудников че да как... А у них просто "компьютер потребовал перезагрузку, а выйти из программы забыли... а что, так разве нельзя???..."

Ответов - 24, стр: 1 2 All

Dima: http://habrahabr.ru/qa/39111/

AlexMyr: Вручную отключить автоматическое обновление! И не требовать от Harbour намного больше

Sergy: Раньше не верил, но сейчас все больше убеждаюсь в мысли, что среднестатистический юзер - не больше, чем обезьянка с клавиатурой. После установки обновлений комп не перегружается автоматом, а лишь предлагает перезагрузку. Нафиг народу о чем-то думать, об открытых таблицах, документах - нажал "перегрузить", вышел покурить - и через пару минут все готово. А то, что в работе может быть куча таблиц, индексов, накладных - да пофиг...


AlexMyr: Sergy пишет: Раньше не верил, но сейчас все больше убеждаюсь в мысли, что среднестатистический юзер - не больше, вот -вот, куда мы катимся? Но это уже разговор в другом разделе не в harbour

Sergy: AlexMyr пишет: вот -вот, куда мы катимся? Но это уже разговор в другом разделе не в harbour Нифига... как раз Harbour должен решить этот вопрос. Винда говорит: "так, всем построиться и выйти нафиг, у нас reboot". А он ей в ответ: постой, паровоз, не стучите колеса, кондуктор, нажми на тормоза... я к юзеру в лапы, с последним приветом спешу показаться на глаза... Вопрос: как получить это системное сообщение от винды в приложение и правильно отработать его ? Уверен, что остальные приложения могут действовать в этой ситуации, а уж базе данных и подавно это жизненно необходимо.

Pasha: Против кнопки RESET лома нет приема Еще один способ перезагрузки (мой любимый): выдернуть сзади питание из системного блока

AlexMyr: Sergy пишет: Нифига... как раз Harbour должен решить этот вопрос. А если у юзера win98, тогда как? Уже было это по letodb, как остановить сервер на этой оси. Sergy пишет: Вопрос: как получить это системное сообщение от винды в приложение и правильно отработать его ? Уверен, что остальные приложения могут действовать в этой ситуации, а уж базе данных и подавно это жизненно необходимо. Это скорее всего обработка ctrl-break для проги. Да и вроде ось не гарантирует при выдаче commit() молниеносного выполнения команды (могу ошибаться).

SergKis: Sergy пишет:как раз Harbour должен решить этот вопрос. Это вопрос обработки сообщений: WM_QUERYENDSESSION и WM_ENDSESSION windows Для терминалов WVT, WIN можно поступить след.образом: 1. в IDLE (организовать on timer) проверку наличия файла <ExeName>.esc и "правильный" выход при наличии 2. Windows программа (запускается до основной) которая, получив вышеуказанные сообщения, создаст файл *.esc, подержит немного windows и завершится. Конечно от ситуации - Pasha пишет:Против кнопки RESET лома нет приема Еще один способ перезагрузки (мой любимый): выдернуть сзади питание из системного блока это не спасет, но хоть что-то. У меня такая штука стоит на letodb и еще на пару программулек

Петр: Sergy пишет: как раз Harbour должен решить этот вопрос Решить вопрос должны Вы Средство регистрации событий завершения работы Windows Средство регистрации событий завершения работы предназначено для регистрации причины, которая привела к перезагрузке или завершению работы компьютера. Затем данную информацию можно просмотреть в журнале событий. Если компьютер под управлением Windows 7 подключен к домену, в котором используются средства наблюдения, сбор данной информации может осуществляться как часть процесса создания отчетов о сети. Если средство регистрации событий завершения работы включено, пользователи не могут осуществить перезагрузку или завершить работу системы без предоставления причины. При неожиданной перезагрузке или неожиданном завершении работы в результате сбоя подачи питания или поломки оборудования пользователю предлагается ввести причину в окне средства регистрации событий завершения работы при следующей загрузке компьютера. Так, что ищите в сети и читайте, узнаете много интересного. К примеру: Отмена перезагрузки или завершения работы Отменить перезагрузку или завершение работы с помощью пользовательского интерфейса регистрации событий завершения работы Windows невозможно. Это можно сделать только с помощью командной строки. Чтобы отменить перезагрузку или завершить работу: Откройте командную строку. Введите shutdown /a в течение периода ожидания. А еще есть API функции, к примеру AbortSystemShutdown, ShutdownBlockReasonCreate..

Sergy: Петр пишет: А еще есть API функции, к примеру AbortSystemShutdown, ShutdownBlockReasonCreate.. Похоже это именно то, что нужно. Осталось научиться получать сообщения WM_QUERYENDSESSION и WM_ENDSESSION upd: Хотя со второй функцией ничего даже ловить не нужно: http://msdn.microsoft.com/library/windows/desktop/aa376877.aspx Applications should call this function as they begin an operation that cannot be interrupted, such as burning a CD or DVD. When the operation has completed, call the ShutdownBlockReasonDestroy function to indicate that the system can be shut down. Но работает только под Vista/Server 2008... http://msdn.microsoft.com/ru-RU/library/windows/desktop/aa376881.aspx Shutdown Notifications Applications with a window and message queue receive shutdown notifications through the WM_QUERYENDSESSION and WM_ENDSESSION messages. These applications should return TRUE to indicate that they can be terminated. Applications should not block system shutdown unless it is absolutely necessary. Applications should perform any required cleanup while processing WM_ENDSESSION. ... Console applications receive shutdown notifications in their handler routines. To register a console handler, use the SetConsoleCtrlHandler function.

Dima: может чем поможет http://clipper.borda.ru/?1-4-360-00000386-000-0-0-1227266107

Sergy: Dima пишет: может чем поможет http://clipper.borda.ru/?1-4-360-00000386-000-0-0-1227266107 О как... оказывается, 5 лет назад этот вопрос уже поднимался. Удалось его закрыть или было принято решение что против лома кнопки reset нет приема ? Дело в том, что переходить на графический интерфейс в ближайшее время пока не собираюсь и в том коде много для меня неясного...

SergKis: Sergy пишет:Удалось его закрыть или было принято решение что против лома кнопки reset нет приема ? Ваша задача должна определять предыдущий запуск был завершен нормально или аварийно. Во втором случае предпринимать определенные действия по проверке целостности данных, перестройке индексов и ...

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

Sergy: SergKis пишет: Ваша задача должна определять предыдущий запуск был завершен нормально или аварийно. Во втором случае предпринимать определенные действия по проверке целостности данных, перестройке индексов и ... Это моя программа делает без вопросов и уже много лет. Единственная проблема - "необъяснимые" вылеты без сообщений об ошибках и логов. Например выяснил, что FUNC Main(); Main(); RETURN выполняется около 9 тысяч раз и вылетает через GPF, не оставив не единого сообщения от Harbour на экране. Вот тут и хотелось-бы понять - что это: юзер нажал на перезагрузку или программа вылетела без участия errorsys. Может быть, проще зайти с другой стороны: наверняка где-нить в реестре хранится дата/время начала текущей сессии. Если ее прочитать и сравнить с временем запуска программы?

AlexMyr: Sergy пишет: FUNC Main(); Main(); RETURN Вы зациклили main()? Sergy пишет: Единственная проблема - "необъяснимые" вылеты без сообщений об ошибках и логов. если вылетов много на день, то вариант самому сесть на место юзера и посмотреть реальную картину или понаблюдать за юзером, что он делает.

Sergy: AlexMyr пишет: Вы зациклили main()? Да. В языках высокого уровня, коим является Harbour, по идее должен быть обработчик ошибок на такой случай. Ведь программист - человек и может ошибиться, написав ошибочный код. Во всяком случае, при компиляции под Windows его нет. Дело доходит до системного GPF. если вылетов много на день, то вариант самому сесть на место юзера и посмотреть реальную картину или понаблюдать за юзером, что он делает. 1-2 в день, да и то не всегда. По сообщениям юзеров - окно просто "схлопывается" без единой ошибки. Настроил пару "мышеловок", в том числе с захватом экрана после завершения процесса (см.в теме про CTRL-BREAK) - посмотрим.

Pasha: Sergy пишет: В языках высокого уровня, коим является Harbour, по идее должен быть обработчик ошибок на такой случай. Ведь программист - человек и может ошибиться, написав ошибочный код. Во всяком случае, при компиляции под Windows его нет. Дело доходит до системного GPF. Это не ошибка, а обычная рекурсия, которая неправильно используется. Рекурсию же не запретишь. Компиляторы С тоже пропускают функцию вроде такой: void ttt(){ttt();}

Sergy: Pasha пишет: Это не ошибка, а обычная рекурсия, которая неправильно используется. Рекурсию же не запретишь. Еще чего не хватало. Нужно лишь ограничить ее глубину и контролировать, только и всего. Компиляторы С тоже пропускают функцию вроде такой: void ttt(){ttt();} Ну так на Си пишут операционные системы, драйверы и прочую системную инженерию вроде самого Harbour. Если там в каждом случае делать проверку на переполнение стека вызовов, мы опять вернемся по тормозам к Windows 95 и процу 486-DX133. А Harbour - язык высокого уровня, на нем пишутся пусть сложные системы, но не требующие высочайшей производительности или отклика в реальном времени. Поскольку там все равно упирается в ширину канала и нагрузку на сервер, скорость жестких дисков, а не такты процессора. PS: недавно проверил, что глубина вызовов deferror/errorsys ограничена числом 8. Свыше этого возникает ошибка 9003. И это правильно. А в Clipper 5.2e подобный код: [pre2]CLEAR SCREEN Main(0) QUIT * -------- * FUNC Main(n) @ 10,10 SAY n Main(n+1) RETURN[/pre2] Вызывает контролируемую Unrecoverable error 650: Processor stack fault примерно через 130 вызовов, а не системный GPF

Pasha: Да будь язык хоть самого сверхвысокого уровня, он не будет блокировать зацикливание при рекурсии, ни на этапе компиляции, ни на этапе интерпретации (когда такой этап имеется). Если знаете такой - напишите. На какой размер блокировать рекурсию ? На 100 ? На 100 тысяч ? А если это необходимо для расчетов ? Это же абсурд. Надо понимать еже такой момент. Любая проверка в vm сказывается на его производительности. Если добавить эту абсурдную проверку, то выполнение всех харбор-функций будет чуть медленнее. Таких абсурдных проверок можно придумать множество. Но проверять такие вещи - не функция vm, а функция программиста. Реакция на абсурдный код непредсказуема, поэтому она разная в клиппере и харборе. Размер стека в клиппере к тому же мизерный по сравнению с харбором. Впрочем, все в Ваших руках. Хотите - напишите в devlist предложение добавить такую проверку, и посмотрите на реакцию.



полная версия страницы