Что нового

OnAutoItErrorRegister - Обработка критических ошибок AutoIt

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 471
Репутация
2 401
AutoIt: 3.3.10.2 - 3.3.12.0
Версия: 2.0

Категория: Вспомогательные функции, Разное

Описание: Данная библиотека позволяет регистрировать функцию вызываемую при критических ошибках AutoIt.
Обычно это синтаксические ошибки, или ошибки связанные с размерностью или не объявлению массивов.
По умолчанию выводит самопальный диалог-отладчик, хотя отлаживать на данный момент конечно нереально, но можно к примеру посмотреть сообщение ошибки, перезапустить программу, отправить отчёт об ошибке, ну или просто закрыть приложение.

Синтаксис и параметры:
Синтаксис вызова:

Код:
_OnAutoItErrorRegister([$sFunction = '' [, $vParams = '' [, $sTitle = '' [, $bUseStdOut = False]]]])
Параметры (все опциональные):

  • $sFunction
    Имя вызываемой функций при перехвате ошибки.
    * Если этот параметр не указан (пустая строка - ""), тогда отображается встроенный диалог обработчика и отладчика ошибки.
    * Функция всегда вызывается с пятью параметрами ($sScriptPath, $iScriptLine, $sError_Msg, $vParams, $hBitmap).
  • $vParams
    Передаваемые пользовательские данные функции $sFunction (по умолчанию "").
  • $sTitle
    Заголовок встроенного диалога обработчика и отладчика ошибки (используется только если $sFunction = "").
  • $bUseStdOut
    Определяет метод отлова ошибок. (по умолчанию False, т.е использовать Hook метод, в данном случае не отлавливает ошибки рекурсии, но в отличии от метода StdOut, не запускает дополнительный процесс слежения и не теряется совместимость при компилировании скрипта в CUI режиме).
  • $bSetErrLine
    Определяет, нужно ли включать обнаружение строки кода с ошибкой в скомпилированном скрипте (по умолчанию False - не включать).


Пример #1 - Вызов встроенного сообщения при получении ошибки:
Код:
#NoTrayIcon

#AutoIt3Wrapper_Run_AU3Check=n
#AutoIt3Wrapper_Run_Before=%autoitdir%\AutoIt3.exe /AutoIt3ExecuteLine "FileClose(FileOpen('%scriptdir%\OAER_RAW_SRC.tmp', 2))"
#AutoIt3Wrapper_Run_After=%autoitdir%\AutoIt3.exe /AutoIt3ExecuteLine "FileDelete('%scriptdir%\OAER_RAW_SRC.tmp')"

#include <GUIConstantsEx.au3>
#include 'OnAutoItErrorRegister.au3'

_OnAutoItErrorRegister('', '', 'My App Error', False, False)

GUICreate('OnAutoItErrorRegister Example', 350, 200)

GUICtrlCreateLabel('This script is just an example.' & @CRLF & @CRLF & 'It will produce a syntax error in', 25, 40, 300, 50)
GUICtrlCreateLabel('5', 185, 50, 50, 40)
GUICtrlSetColor(-1, 0xF20000)
GUICtrlSetFont(-1, 30, 800, 0, 'Tahoma')
GUICtrlCreateLabel('seconds.', 220, 67, 300, 50)
GUICtrlCreateLabel('The result shown as a CUSTOM error message, you can change it!', 25, 120, 350, 20)
$iUnRegister_Bttn = GUICtrlCreateButton('UnRegister AutoItError handler', 25, 140, 200, 22)
GUICtrlCreateLabel('Copyright jennico, G.Sandler (MrCreatoR) © 2008 - 2015', 25, 170, 350, 80)
GUICtrlSetColor(-1, 0x808080)
GUICtrlSetFont(-1, 8.5, 800, 6)

GUISetState()

Dim $iTimer

For $i = 3 To 1 Step -1
	GUICtrlSetData(4, $i)
	
	$iTimer = TimerInit()
	
	While TimerDiff($iTimer) < 1000
		Switch GUIGetMsg()
			Case $GUI_EVENT_CLOSE
				Exit
			Case $iUnRegister_Bttn
				_OnAutoItErrorUnRegister()
		EndSwitch
	WEnd
Next

;We deliberately make a syntax mistake and call the error!
If Random(1, 5, 1) = 3 Then
	MsgBox(0, '', )
Else
	_NotExistingFunc()
EndIf

Пример #2 - Вызов собственной функций при получении ошибки (перезапуск скрипта):
Код:
#NoTrayIcon

#AutoIt3Wrapper_Run_AU3Check=n
;!!! This must be used to ensure that raw source file is generated before compilation (because $bSetErrLine is True)
#AutoIt3Wrapper_Run_Before=%autoitdir%\AutoIt3.exe "%in%" /BC_Strip
#AutoIt3Wrapper_Run_After=%autoitdir%\AutoIt3.exe /AutoIt3ExecuteLine "FileDelete('%scriptdir%\OAER_RAW_SRC.tmp')"

#pragma compile(Stripper, False)

#include 'OnAutoItErrorRegister.au3'

_OnAutoItErrorRegister('_MyErrorHandler', '', '', False, True)

;We deliberately make an array bounding error and call the error!
Dim $aArr[1]
MsgBox(0, '', $aArr[1])

Func _MyErrorHandler($sScriptPath, $iScriptLine, $sErrDesc, $vParams, $hBitmap) ;Restart the application
	Local $sMessage = StringFormat('SCRIPT FILE:\n%s\n\nSCRIPT ERROR LINE:\n%s\n\nERROR DESCRIPTION:\n%s', $sScriptPath, $iScriptLine, $sErrDesc)
	
	If StringInStr($CmdLineRaw, '/ErrorStdOut') Then
		If FileExists(@WindowsDir & "\Media\chord.wav") Then
			SoundPlay(@WindowsDir & "\Media\chord.wav")
		Else
			DllCall('user32.dll', 'int', 'MessageBeep', 'int', 0x00000010)
		EndIf
	EndIf
	
	If MsgBox(BitOR($MB_SYSTEMMODAL, $MB_YESNO), 'Crash recieved!', 'Restart application?' & @CRLF & @CRLF & $sMessage) <> 6 Then
		Return
	EndIf
	
	Local $sRunLine = @AutoItExe & ' "' & @ScriptFullPath & '"'
	
	If @Compiled Then
		$sRunLine = @ScriptFullPath
	EndIf
	
	Run($sRunLine, @ScriptDir)
EndFunc

Файл: OnAutoItErrorRegister.zip

Снимок:


История версий:
v2.0
* Библиотека переписана (использованы методы с библиотеки AutoItErrorTrap).
- Изменён синтаксис, см. описание к функции вызова.
* Убрана поддержка AutoIt 3.3.8.1.
+ Добавлена возможность захвата экрана при ошибке. Файл может быть отправлен как вложение при использовании функции "Send Bug Report".

v1.9
+ Добавлено определение строки с ошибкой для скомпилированного скрипта (для отображения самой строки которая вызвала ошибку).
Скрипт должен быть запущен перед компиляцией (после любого изменения в нём), или используйте '#AutoIt3Wrapper_Run_Before=%autoitdir%\AutoIt3.exe "%in%" /BC_Strip' в основном скрипте.
!!! НЕ используйте Au3Stripper при компиляции скрипта.
+ Добавлено определение повторного запуска обработчика (для предотвращения многократного рекурсивного запуска).
* Исправлена проблема с ком. строкой.

v1.8
+ Добавлена совместимость с 3.3.12.0.
+ Добавлена функция _OnAutoItErrorUnRegister (см. Пример 1).
* Теперь callback-функция ($sFunction) в _OnAutoItErrorRegister всегда принимает 4 парааметра ($sScriptPath, $iScriptLine, $sErrDesc, $vParams).
* Внутренние функции переименованы с __OnAutoItErrorRegister_* на __OAER_*.
* Убрано использование командной строки для определения повторного запуска скрипта.
* Более стабильное определение сообщения об ошибке AutoIt (при $bUseStdOutMethod = False).
* Исправлена проблема когда главный скрипт (или другая UDF) использует Opt('MustDeclareVars', 1).

v1.7
* Исправлена проблема с отображением иконки даже при использований #NoTrayIcon.
* Исправлена проблема с передачей начальных параметров командной строки.
Теперь также добавляется параметр /OAER к командной строке, это идентификатор для библиотеки OnAutoItErrorRegister.

v1.6
* Исправлена проблема с перехватом COM ошибок (эта библиотека не предназначена для отлова COM ошибок, COM-обработчик используется только для функций отправки отчёта об ошибке).
* Убран лишний #include <File.au3>.
* Исправлена проблема с автонажатием кнопок в диалогах на Windows Vista/7.

v1.5
* Исправлена проблема с высокой загрузкой ЦП.
* Опция отправки баг репорта ("Send bug report") значительтно улучшена.
* Добавлена возможность перевести все элементы библиотеки на свой язык - см. раздел "User Variables".
* Косметические поправки в коде.

v 1.4
Библиотека доработана и почти полностью переписана.

Источник: www.autoit-script.ru
Автор(ы): G.Sandler (CreatoR), jennico


Примечания:
  • Библиотека не может отлавливать ошибки связанные с утечкой памяти, такие как сбои DllCall, рекурсии ("Recursion level has been exceeded...") (при использовании метода Hook ($bUseStdOut = False)).
  • При использовании метода StdOut ($bUseStdOut = True) невозможно использовать режим CUI, а также запускается дополнительный процесс для слежения за ошибками.
  • После использования _OnAutoItErrorUnRegister с указанием $bUseStdOut = True, стандартное сообщение об ошибке не будет отображаться.
  • Для функций отправки отчёта об ошибке ("Send bug report"), нужно внимательно заполнить параметры (переменные) в секций «User Variables» файла библиотеки, присмотритесь к комментариям у переменных.

  • [Если $bSetErrLine = True...]
    • Скрипт должен быть запущен перед компиляцией (после любого изменения в нём), или используйте «#AutoIt3Wrapper_Run_Before=%autoitdir%\AutoIt3.exe "%in%" /BC_Strip» в основном скрипте.
    • !!! НЕ используйте Au3Stripper при компиляции скрипта.
    • Для получения корректной строки кода с ошибкой для скомпилированного скрипта, скрипт преобразовывается в цельный исходный файл (слияние всех Includ'ов) и распаковывается используя FileInstall при необходимости (при ошибке), поэтому исходный файл скрипта доступен во временном каталоге на несколько мгновений (на момент поступления ошибки), и не смотря на то что он зашифрован, разработчик должен принять меры для более надёжной защиты своего скрипта.

  • [Если $bSetErrLine = False...]
    • Используйте предоставленный инструмент GetErrLineCode.au3 для получения корректной строки кода с ошибкой по номеру строки полученной от сообщения об ошибке из скомпилированного скрипта.
 

Belfigor

Модератор
Локальный модератор
Сообщения
3 590
Репутация
938
Ухты, а эта штука планирует развиваться в нечто большее?
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 471
Репутация
2 401
Belfigor [?]
эта штука планирует развиваться в нечто большее?
Наврядли, да и я тоже не планирую её развивать особо :laugh:

А что ещё нужно?
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 471
Репутация
2 401
Обновление...

v1.5
* Исправлена проблема с высокой загрузкой ЦП.
* Опция отправки баг репорта ("Send bug report") значительтно улучшена.
* Добавлена возможность перевести все элементы библиотеки на свой язык - см. раздел "User Variables".
* Косметические поправки в коде.
 

asdf8

Скриптер
Сообщения
564
Репутация
152
Belfigor
для отладки неплохо подходит это
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 471
Репутация
2 401
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 471
Репутация
2 401
Небольшое обновление.

[1.6]
* Исправлена проблема с перехватом COM ошибок (эта библиотека не предназначена для отлова COM ошибок, COM-обработчик используется только для функций отправки отчёта об ошибке).
* Убран лишний #include <File.au3>.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711


Причем закрыть это получается только по Ctrl+Alt+Del.

Windows 7 x86

:(
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 471
Репутация
2 401
Yashied
Yashied сказал(а):
Причем закрыть это получается только по Ctrl+Alt+Del.
Стоп, а кнопка "Ок" разве не нажимается? :scratch:

По поводу отправки, ты правильно заполнил переменные почтового аккаунта?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
"OK" нажимается, но тут же это окно появляется снова. Заполнить я ничего не могу, т.к. ошибка возникает сразу же после нажатия "Send bug report" (в основном окне, маленьком).
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 471
Репутация
2 401
Yashied [?]
"OK" нажимается, но тут же это окно появляется снова
Нужно было с этого и начинать, что без запроса нажимается кнопка отправки.
Это видимо из за того что на Win7 иконок нет, поэтому элемент не создаётся и возвращается 0.
Поправим...
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 471
Репутация
2 401
Yashied [?]
Заполнить я ничего не могу, т.к. ошибка возникает сразу же после нажатия "Send bug report"
Я про данные в переменных.

Попробуй проверить, после замены (в двух местах):
Код:
If $nMsg > 0 And Not __OnAutoItErrorRegister_ClickProc($nMsg, $hSndBugRprtGUI) Then

на
Код:
If $nMsg = 0 Or ($nMsg > 0 And Not __OnAutoItErrorRegister_ClickProc($nMsg, $hSndBugRprtGUI)) Then

будет проявляться проблема с автонажатием?

P.S
Или например заменить "shimgvw.dll", -6 на "shell32.dll", -157.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 471
Репутация
2 401
Yashied
Ау... :whistle:
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
CreatoR сказал(а):
Попробуй проверить, после замены...
Да, так работает! Может лучше использовать shell32.dll для иконок?

P.S

Я обычно в цикле делаю так:

Код:
Switch $nMsg
	Case 0
		ContinueLoop
	...
EndSwitch
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 471
Репутация
2 401
Небольшое обновление...
* Исправлена проблема с автонажатием кнопок в диалогах на Windows Vista/7.
Версия осталась прежней.
 

andr_mozg

Новичок
Сообщения
15
Репутация
0
Спасибо за UDF...
есть пару вопросов

использую в программе , при ошибки используюет указанную функцыю
вопрос
у меня стоит параметр
#NoTrayIcon
при использовании _OnAutoItErrorRegister
в треи значек есть.. как убрать?
и еще вопрос
как мне записать в фай информацыю о ошибке, линия и кусок кривого кода

спасибо
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 471
Репутация
2 401
Обновление:

[1.7]
* Исправлена проблема с отображением иконки даже при использований #NoTrayIcon.
* Исправлена проблема с передачей начальных параметров командной строки.
Теперь также добавляется параметр /OAER к командной строке, это идентификатор для библиотеки OnAutoItErrorRegister.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 471
Репутация
2 401
andr_mozg [?]
как мне записать в фай информацыю о ошибке
Открыть файл, нажать Debug Script, скопировать оттуда нужную информацию, и записать её в файл :laugh:.
 

ShSergey

Новичок
Сообщения
12
Репутация
1
В следующем коде при нажатии PAUSE значение глобальной переменной $VerPrinttest неверное (не равно 2).
Если убрать _OnAutoItErrorRegister("_MyErrorHandler") то все нормально.
Подскажите, пожалуйста, что нужно сделать чтобы значение глобальной переменной $VerPrinttest при использовании _OnAutoItErrorRegister("_MyErrorHandler") было верное ?

Код:
#include <OnAutoItErrorRegister.au3>

Global $VerPrinttest

HotKeySet("{PAUSE}", "PrintBirka") 
_OnAutoItErrorRegister("_MyErrorHandler")

Func PrintBirka()	
	MsgBox(0,"$VerPrinttest",$VerPrinttest,2)   		
	Exit
EndFunc

$VerPrinttest = 2

While 1	
	Sleep(1000)
WEnd

Func _MyErrorHandler() ;Restart the application
    If MsgBox(52, 'Crash recieved', 'Restart application?') <> 6 Then
        Return
    EndIf
   
    Local $sRunLine = @AutoItExe & ' "' & @ScriptFullPath & '"'
   
    If @Compiled Then
        $sRunLine = @ScriptFullPath
    EndIf
   
    Run($sRunLine, @ScriptDir)
EndFunc
 
Верх