Форум » GUI » Вылет из программы... » Ответить

Вылет из программы...

Andrey: Всем привет ! Как можно в МиниГуи программе сделать вызов своих функций при аварийном завершении программы (т.е. при вылете) ? Т.е. хочу сделать сразу после появления MsgBox() вызов 2-3 функций и потом сделать DbCloseAll(). Как это реализовать ? Для чего это нужно, поясню: при входе в свою программу я пишу в базу кто и когда вошел в программу (логин пользователя). И при выходе из программы, стираю этого пользователя из базы. Если программа "вылетает", то юзер числится как работающий. Древнее наследие с клипера, хотел переделать, да так и осталось.

Ответов - 19

Haz: Andrey пишет: Как можно в МиниГуи программе сделать вызов своих функций при аварийном завершении программы (т.е. при вылете) изменить стандартный обработчик ошибок. см. Errorsys.prg

Andrey: Haz пишет: изменить стандартный обработчик ошибок. см. Errorsys.prg Т.е. нужно будет сделать следующее: 1) Изменить файл MiniGUI\SOURCE\ErrorSys.prg под себя - примерно так: [pre2]STATIC PROCEDURE ShowError( cErrorMessage, oError ) *-----------------------------------------------------------------------------* STATIC _lShowError := .T. IF _lShowError _lShowError := .F. #ifdef _TSBROWSE_ _TSB_aControlhWnd := {} #endif MsgStop( iif( _lShowDetailError(), cErrorMessage, ErrorMessage( oError ) ), 'Program Error', NIL, .F. ) ErrorLevel( 1 ) MyExitFunction() // вызов моих функций DbCloseAll() // закрыть все базы ReleaseAllWindows() ENDIF RETURN[/pre2] 2) Добавить этот файл к себе в проект. Достаточно этого будет ? Дело в том, что не всегда на сервере закрываются базы ! Приходиться вручную закрывать открытые базы пользователя. Не знаю кто оставляет их открытыми: терминалка на хХарборе или МиниГуи. Но с таким периодически я сталкиваюсь. Если в качестве сервера юзера пользуются Win ХР, то такое бывает чаще. А избавиться от ХР никак не получается.

Haz: Andrey пишет: Достаточно этого будет ? Чтоб не писать свой обработчик ошибок. Можно и так. Этого достаточно.


Vlad04: "Опасные" участки программы обрамить конструкцией try catch MyExitFunction() // вызов моих функций DbCloseAll() // закрыть все базы end

Dima: Andrey пишет: И при выходе из программы, стираю этого пользователя из базы. Rlock() записи юзера не подходит ? Если вылет , запись разблокируется (надеюсь что так).

Andrey: Vlad04 пишет: "Опасные" участки программы обрамить конструкцией try catch MyExitFunction() // вызов моих функций DbCloseAll() // закрыть все базы end Это лишнее. Опасные участки я делаю через такой код примерно: [pre2] BEGIN SEQUENCE WITH { |e|break( e ) } .... RECOVER .... END SEQUENCE[/pre2] Этого достаточно. Dima пишет: Rlock() записи юзера не подходит ? Нет, не подходит. Если программа аварийно слетела или ещё какие то причины (не знаю какие) база на сервере (даже Win2008) остаётся открытой, т.е. занятой пользователем. Такое редко на Win2008 бывает. И приходиться вручную через панель администратора закрывать базы, а там штук 60 баз... 60 раз кликов мышки на файл, потом на кнопку закрыть. Работа та ещё. Или сервер перегрузить нужно, но всех юзеров замучишься по кабинетам обходить и выгонять из подключений к серверу.

Andrey: Сделал как посоветовал Haz ! Отлично работает ! MyExitFunction() // вызов моих функций - отрабатывает нормально. Дело в том что у меня главная программа на МиниГуи, через неё вызываю терминальные окна программы и запоминаю хендлы открытых окон, а при аварийном вылете программы на МиниГуи, закрываю заодно и терминальные окна. Классно проходит закрытие... Заодно и пользователя из dbf-журнала пользователей программы (кто в программе) удаляю. Спасибо за помощь !

Andrey: Привет всем ! Появился у меня вылет из программы, при сбое соединения с PostgreSQL. При сбое отправки в PostgreSQL вывожу окно MODAL. А оно не выводиться. Появляется вот такая ошибка и вылет: [pre2]Error MGERROR/0 Release a window in its own ON RELEASE procedure or release the Main Window in any ON RELEASE procedure is not allowed. Program terminated. Called from MSGMINIGUIERROR(0) Called from RELEASEALLWINDOWS(0) Called from SHOWERROR(194) in module: Source\ErrorSys.prg Called from DEFERROR(131) in module: Source\ErrorSys.prg Called from (b)ERRORSYS(64) in module: Source\ErrorSys.prg Called from MSGMINIGUIERROR(0) Called from _ACTIVATEWINDOW(0) Called from WAIT_WINDOW_MY(308) in module: Source\WaitWin.prg Called from WAITWINDOWERROR(157) in module: Source\WaitWin.prg Called from FIELDSTOPGSQLZAIV2(776) in module: Source\form_site.prg Called from COPYPGSQL3ALGORITM(1275) in module: Source\form_site.prg .........[/pre2] Как исправить эту ошибку ? Что нужно делать ? P.S. ErrorSys.prg добавлен свой, чуть-чуть скорректирован, как Игорь посоветовал.

SergKis: Andrey Возможно делаешь CloseAllWindow(), а где то в др. окне в on release\on interactiveclose делаешь вызов ее или Form_?.Release или DoMethod(..., 'Release'), похоже на такой компот ...

Andrey: SergKis пишет: Возможно делаешь CloseAllWindow() Нет, не делаю. Ошибка приходит из PostgreSQL, текстовая строка, сделал вывод в отладку - нормально выглядит. Called from FIELDSTOPGSQLZAIV2(776) in module: Source\form_site.prg вот кусок кода: [pre2] IF nResultStatus == PGRES_COMMAND_OK .... ELSE cMsg += " - Результат: " + GetResultStatus( nResultStatus, 2 ) + " - " cMsg += GetResultStatus( nResultStatus, 3 ) + CRLF + CRLF cMsg += "Файл ошибки: " + cFileNoPath( ChangeFileExt( cFile, ".err" ) ) + CRLF ? VALTYPE(cMsg) ? cMsg WaitWindowError(cMsg) // строка 776 ENDIF[/pre2] Функции простые, работают в других местах без сбоев: Called from WAIT_WINDOW_MY(308) in module: Source\WaitWin.prg Called from WAITWINDOWERROR(157) in module: Source\WaitWin.prg А что за ошибки такие, перед ними: [pre2]Called from MSGMINIGUIERROR(0) Called from RELEASEALLWINDOWS(0) Called from SHOWERROR(194) in module: Source\ErrorSys.prg Called from DEFERROR(131) in module: Source\ErrorSys.prg Called from (b)ERRORSYS(64) in module: Source\ErrorSys.prg Called from MSGMINIGUIERROR(0) Called from _ACTIVATEWINDOW(0) [/pre2] ?

PSP: Andrey пишет: А что за ошибки такие, перед ними: Called from MSGMINIGUIERROR(0) Called from RELEASEALLWINDOWS(0) Called from SHOWERROR(194) in module: Source\ErrorSys.prg Called from DEFERROR(131) in module: Source\ErrorSys.prg Called from (b)ERRORSYS(64) in module: Source\ErrorSys.prg Called from MSGMINIGUIERROR(0) Called from _ACTIVATEWINDOW(0) Видимо твой подкорректированный Errorsys и есть причина того что "Error MGERROR/0 Release a window in its own ON RELEASE procedure or release the Main Window in any ON RELEASE"

SergKis: Andrey пишет А что за ошибки такие, перед ними: это стек вызовов в момент ошибки используй begin sequnce, что бы не падало и вывели тексты не в окно. а в log.

SergKis: Andrey пишет Появляется вот такая ошибка и вылет: Error MGERROR/0 Release a window in its own ON RELEASE procedure or release the Main Window in any ON RELEASE Нет, не делаю [pre2] *-----------------------------------------------------------------------------* FUNCTION _ReleaseWindow ( FormName ) *-----------------------------------------------------------------------------* ... IF _HMG_ThisEventType == 'WINDOW_RELEASE' IF GetFormIndex ( FormName ) == _HMG_ThisIndex MsgMiniGuiError( "Release a window in its own ON RELEASE procedure or release the Main Window in any ON RELEASE procedure is not allowed." ) ENDIF ENDIF * If the window to release is the main application window, RELEASE ALL WINDOWS command will be executed IF GetWindowType ( FormName ) == 'A' IF _HMG_ThisEventType == 'WINDOW_RELEASE' MsgMiniGuiError( "Release a window in its own ON RELEASE procedure or release the Main Window in any ON RELEASE procedure is not allowed." ) ELSE ReleaseAllWindows() ENDIF ENDIF ... [/pre2] т.е. уже находясь в событии release window -> IF _HMG_ThisEventType == 'WINDOW_RELEASE', выполняется новый release window

Andrey: SergKis пишет: т.е. уже находясь в событии release window -> IF _HMG_ThisEventType == 'WINDOW_RELEASE', выполняется новый release window Да не делаю я нигде WINDOW_RELEASE. Программа работает нормально. Как приходит ошибка отправки в PostgreSQL, то и появляется эта ошибка. Поставил вывод в лог-файл и убрал вызов моей функции WaitWindowError(cMsg). Программа перестала падать. Значит дело в моей функции WaitWindowError(cMsg), т.е. там не может создать окно. Вроде делаю всё как обычно... Непонятки одни с этим окном.

SergKis: Andrey пишет Непонятки одни с этим окном. STATIC PROCEDURE OnRelease() ThisWindow.Release ... если This окно, по какой то причине, Form_Main, то release вызовет RELEASEALLWINDOWS(0), т.к. окно не проявляется, то вполне может залезть в ситуацию сообщения "Release a window in its own ON RELEASE..." поставь трассировку по WaitWindowError - куда лезет узнаешь

Andrey: SergKis пишет: поставь трассировку по WaitWindowError - куда лезет узнаешь Я уже пытался. Подскажи как ?

SergKis: Andrey пишет Подскажи как ? Пример (на идеи из BASIC\WAIT_WINDOW_2) на событиях без потоков. http://my-files.ru/1ykqd9 Твой WaitWindowError можно сделать аналогично.

SergKis: PS Если сделать правку, будет нагляднее по окнам[pre2] FUNCTION StartWait( oWnd, nEvent ) ... LOCAL aWnd := array(4) WHILE _IsWindowDefined( cWnd := '_w_' + hb_ntos( ++nId ) ) END cTitle += ' ' + hb_ntos( nId ) aWnd[1] := { nY , nX } ... [/pre2]

SergKis: Может будет интересно, пример продолжение http://my-files.ru/gkupot Добавлен выбор, дублклик в календаре и перенос выбора на wait окна



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