Что нового

Как сделать чтобы при запуске скрипта из другого скрипта не выскакивало окно с ошибкой

joker2d

Новичок
Сообщения
182
Репутация
0
Запускаю скрипт NEW_BD_backup.au3 из другого сприпта main_backup.au3

Код:
$iPID = Run(FileGetShortName(@AutoItExe) & " /AutoIt3ExecuteScript " & FileGetShortName("C:\Autoit_code\NEW_BD_backup.au3"), @WorkingDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)

    While 1
        $sOut &= StdoutRead($iPID, False)        
        If @error Then
            ConsoleWrite("log posle =" & $sOut & @CRLF)
            ExitLoop
        EndIf
    WEnd


Если в коде скрипта NEW_BD_backup.au3 есть ошибка то выскакивает всплывающее окно например такое
1687061627690.png
которое блокирует выполнение скрипта main_backup.au3 и надо нажимать ОК
можно ли как то сделать запуск скрипта NEW_BD_backup.au3 чтобы при ошибке в коде я сам ее обрабатывал в main_backup.au3
слал например сообщение куда то или в лог писал, главное чтобы было понятно что была ошибка и работа не останавливалась
 

All2khoff

Продвинутый
Сообщения
371
Репутация
67
Собственно проверяйте наличие окна с данным заголовком.

Код:
Sleep (5000) ;задержка 5 секунд
If WinExists("Autoit Error") Then
    ;если окно есть, действуем по плану один
Else
    ;Если окна нет действуем по плану два
EndIf
 
Автор
J

joker2d

Новичок
Сообщения
182
Репутация
0
Собственно проверяйте наличие окна с данным заголовком.
А внутри кода никак не промониторить что такое окно есть ? или просто запускать скрипт так чтобы оно не появлялось, когда я просто запускаю второй скрип с той же ошибкой такое окно не появляется просто в консоли пишет что скрипт завершился с ошибкой и все
 

All2khoff

Продвинутый
Сообщения
371
Репутация
67
Появление данного окна это "Исключительная ошибка", вам либо в коде все причесать надо, либо делать внешний обработчик ошибок как предложил я.
Лучшим решением будет запускать не *.au3 а компилировать их в *.exe тогда можно будет материнским скриптом все это комфортно отслеживать.
По крайней мере я так вижу.
 
Автор
J

joker2d

Новичок
Сообщения
182
Репутация
0
Появление данного окна это "Исключительная ошибка", вам либо в коде все причесать надо, либо делать внешний обработчик ошибок как предложил я.
Лучшим решением будет запускать не *.au3 а компилировать их в *.exe тогда можно будет материнским скриптом все это комфортно отслеживать.
По крайней мере я так вижу.
ну так если компилировать в ехе я не увижу вывод в консоль, я хочу если случиться ошибка посмотреть что пишет в консоль скрипт
 

All2khoff

Продвинутый
Сообщения
371
Репутация
67
Так можно писать в файл... это надежней.
Код:
FileWrite ( "filehandle/filename", "text/data" )
 
Автор
J

joker2d

Новичок
Сообщения
182
Репутация
0
Так можно писать в файл... это надежней.
Код:
FileWrite ( "filehandle/filename", "text/data" )
ну то есть вместо команды ConsoleWrite использовать FileWrite ?
А если ошибка с указанием номера строки, как это в файл записать, это же как понимаю только в консоле можно увидель, а это самое главное при проблеме
Сообщение автоматически объединено:

и еще оказывается

Код:
Sleep(5000)
        If WinExists("Autoit Error") Then
            ConsoleWrite("ERORR DETECTED" & @CRLF)
        endif

Не работает, когда появляется окно с ошибкой, скрипт main_backup.au3 полностью блокируется и не работает пока я сам не нажму ОК в окне с ошибкой
и что делать ?
 
Последнее редактирование:

All2khoff

Продвинутый
Сообщения
371
Репутация
67
мониторить окно должен отдельный скрипт...
А если ошибка с указанием номера строки
запись в консоль используется обычно для отладки, а именно для приведения скрипт к работе без ошибок, в дальнейшем же вывод в лог идет для мониторинга.
использовать сырец скрипта без компиляции это не самый верный путь.
А по уму надо разбираться не в том как обойти ошибку, а исправить её)
Попробуй в начале кода проблемного скрипта написать
Код:
Global $b =0

а то есть подозрение что переменная не объявлена а ты уже пытаешься к ней математические действия применять.
 
Автор
J

joker2d

Новичок
Сообщения
182
Репутация
0
Да я эту ошибку искусственно сделал чтобы проверить что будет при ошибке, ошибки могут проявиться и через месяц и через год и я хотел бы видеть что пишет в консоль

Ну как бы получается схема надо запускать три скрипта, 1) один мониторит ошибку с окном Autoit Error 2) скрипт который Запускает основной скрипт 3) Сам скрипт с полезной нагрузкой
Точно нельзя проще ?
 

All2khoff

Продвинутый
Сообщения
371
Репутация
67
Гадая вилкой по борщу я больше информации дать не смогу.
В идеале в данном случае картина должна быть такая....
1. Материнский скрипт, который мониторит ошибки, ведет логи, запускает другие скрипты...
2. Скрипт с полезной нагрузкой, который "может упасть".
Но для упрощения, лучше использовать такой вариант.
1. Скрипт мониторит ошибки.
2. Материнский скрипт, который запускает другие скрипты и ведет логи запуска.
3. Полезный скрипт, который "может упасть"
4. И всё это скомпилировано.
поидее процендуру резервного копирования баз данных не надо так сильно усложнять, но опять же кухня ваша...
 
Автор
J

joker2d

Новичок
Сообщения
182
Репутация
0
В идеале в данном случае картина должна быть такая....
1. Материнский скрипт, который мониторит ошибки, ведет логи, запускает другие скрипты...
2. Скрипт с полезной нагрузкой, который "может упасть".
ну так я не могу понять как это сделать по вашему первому варианту когда материнский скрипт не может продолжить работу если ошибка в скрипте с полезной нагрузкой останавливает его работу ?

поидее процендуру резервного копирования баз данных не надо так сильно усложнять, но опять же кухня ваша...
я буду применять для всего, резервное копирование как пример, да там ошибок может быть мало, но бывало что работал неск месяцев, а потом завис и ничего не писал так же несколько месяцев, а это очень не приятно
 

All2khoff

Продвинутый
Сообщения
371
Репутация
67
ошибка в скрипте с полезной нагрузкой
дело в том что скрипты не скомпилированы, об этом я уже писал.
несколько месяцев
Именно потому нужны логи а не консоль, так же можно написать скрипт который будет сигнализировать о том что логи с определенной записью не появлялись последние условные 24 часа...
Данный ЯП очень гибок и может многое, но работая с нескомпилированным вариантом вы сами себя ограничиваете.

Как пример решения 3й скрипт в скомпилированном виде запустите и пробуйте опыт со сломанным скриптом...
Код:
While = 1
    Sleep (60000) ;задержка 60 секунд
    If WinExists("Autoit Error") Then
        ;если окно есть, действуем по плану один
        WinActivate("Autoit Error")
        Sleep(100)
        WinWaitActive("Autoit Error")
        Sleep(100)
        Send("{ENTER}")
    Else
        ;Если окна нет действуем по плану два
    EndIf
WEnd
 
Последнее редактирование:

joiner

Модератор
Локальный модератор
Сообщения
3,557
Репутация
628
Нужно в коде предусматривать появление ошибки. Он не должен крашиться, даже через месяц
 
Автор
J

joker2d

Новичок
Сообщения
182
Репутация
0
Данный ЯП очень гибок и может многое, но работая с нескомпилированным вариантом вы сами себя ограничиваете.
Можно вот это поподробней объяснить
Всегда считал что если я запускаю аутоит скрипт в редакторе кода раньше это был SciTE сейчас я перешел на VS Code, то при любой ошибке я получу номер строки или даже строк в которой она произошла и могу попытаться ее исправить, а если я скомпилирую скрипт, то я просто получу сам факт того что была ошибка и это мне ни как не поможет исправить проблему, разве я не прав?

Я понял что при скомпилированом скрипте можно писать логи, можно третим скриптом ловить окно с ошибкой и мониторить файл логов, ну а строку в которой произошла ошибка как я узнаю ?
 

joiner

Модератор
Локальный модератор
Сообщения
3,557
Репутация
628
Ссылка на пост с методом определения строки ошибки
 
Автор
J

joker2d

Новичок
Сообщения
182
Репутация
0
Ссылка на пост с методом определения строки ошибки
там пост 2015 года скрипт поддерживает только старые весрии аутоит
Global $sAutoItExe = @AutoItExe ;Should be 3.3.12.0 / 3.3.9.4 / 3.3.8.X / 3.3.6.X

может поновее есть ? и что он делает я его запустил надо выбрать какой то файл а что выбирать au3 или скомпилированный exe и потом что ?
 

SealAlbinos

Продвинутый
Сообщения
155
Репутация
58
там пост 2015 года скрипт поддерживает только старые весрии аутоит
Global $sAutoItExe = @AutoItExe ;Should be 3.3.12.0 / 3.3.9.4 / 3.3.8.X / 3.3.6.X

может поновее есть ? и что он делает я его запустил надо выбрать какой то файл а что выбирать au3 или скомпилированный exe и потом что ?
скрипт отлично работает и на последних версиях, да и там все прекрасно написано
применить к ИСХОДНИКУ скрипта, т.е выбрать исходник и написать номер строки, где вылетела ошибки уже в скомпилированной программе, чтоб в дальнейшем уже исправить в самом исходнике (скрипт выдаст номер строки именно в исходнике не учитывая библиотеки)
 

joiner

Модератор
Локальный модератор
Сообщения
3,557
Репутация
628
Все сложные проекты перед компилированием обрабатываю указанным кодом.
Получается исходник со всеми включенными библиотеками. Вот в нем как раз ищешь строку с ошибкой.
И да, работает на новой версии языка.
 
Автор
J

joker2d

Новичок
Сообщения
182
Репутация
0
скрипт отлично работает и на последних версиях, да и там все прекрасно написано
применить к ИСХОДНИКУ скрипта, т.е выбрать исходник и написать номер строки, где вылетела ошибки уже в скомпилированной программе, чтоб в дальнейшем уже исправить в самом исходнике (скрипт выдаст номер строки именно в исходнике не учитывая библиотеки)
либо я чего не понимаю, либо все таки новую версию аутоит этот скрипт поддерживает плохо
1) Из au3 скрипта запустил exe с искусственной ошибкой, получил окно Autoit Error и номер строки с ошибкой
2) Выбрал au3 скрипт из которого скомпилировался exe и вбил номер строки полученную в окне Autoit Error
В итоге номера строки из au3 файла где ошибка он НЕ выдает, он выводит саму строку (то есть код который есть в этой строке), НО даже тут неправильно, ошибка была ниже по коду, то есть даже строку без номера указывает неправильно
Сообщение автоматически объединено:

Все сложные проекты перед компилированием обрабатываю указанным кодом.
не очень понял как именно обрабатываете перед компилированием
при запуске скрипт просит выбрать au3 файл и потом ввести номер строки, как тут обработать что то перед компилированием ?
использую скрипт на который вы дали ссылку (где в коде в самом начале Select script file (source from your compiled script))
 

joiner

Модератор
Локальный модератор
Сообщения
3,557
Репутация
628
вот так
Код:
#RequireAdmin
#include <WinAPIFiles.au3>

Global $sAutoItExe = @AutoItExe
$sFile = FileOpenDialog('Select script file (source from your compiled script)...', @ScriptDir, 'AutoIt v3 Script (*.au3)')
If @error Then Exit
_AU3_GetErrLineCode($sFile)

Func _AU3_GetErrLineCode($sScript_File)
    Local $sSrc_Raw, $iPos1, $iPos2, $iLen
    $sSrc_Raw = _AU3_StripToRaw($sScript_File)
    If @error Then
        Return SetError(1, 0, '')
    EndIf
    $sSrc_Raw = StringStripWS($sSrc_Raw, 3)
    $sScript_File = StringTrimRight($sScript_File, 4)
    Local $fo = FileOpen($sScript_File & '_Raw.au3', 2)
    FileWrite($fo, $sSrc_Raw)
    FileClose($fo)
EndFunc

Func _AU3_StripToRaw($sSrcFile, $bReset = False)
    If $sSrcFile = '' Or Not FileExists($sSrcFile) Then
        Return SetError(1, 0, 0)
    EndIf

    Local Static $sSrcRaw = ''
    Local Static $sInclds = '|'

    If $bReset Then
        $sSrcRaw = ''
        $sInclds = '|'
    EndIf

    Local $sInclude = '', $sLine = '', $iPos = 0, $sFName = '', $sFnc = '', $aFnc, $aVars
    Local $sScriptDir = StringRegExpReplace($sSrcFile, '\\[^\\]+$', '')
    Local $sRead = FileRead($sSrcFile)

    ;!!! Strip comment block here (before checking #include-once)...
    _AU3_StringStripCommentBlocks($sRead)

    If StringRegExp($sRead, '(?mi)^\h*#include-once') Then
        If StringInStr($sInclds, '|' & $sSrcFile & '|', 2) Then
            $sRead = StringRegExpReplace($sRead, '(?msi)\R?^\h*#include-once.*', '')
        Else
            $sInclds &= $sSrcFile & '|'
        EndIf
    EndIf

    $sRead = StringStripCR($sRead)
    Local $aRead = StringSplit($sRead, @LF)

    For $i = 1 To $aRead[0]
        If StringStripWS($aRead[$i], 8) = '' Then
            ContinueLoop
        EndIf

        If StringRegExp($aRead[$i], '(?i)^\h*(;|#include-once|#pragma\h+compile\()') Then
            ContinueLoop
        EndIf

        _AU3_StringStripComments($aRead[$i])

        If Not StringRegExp($aRead[$i], '(?i)^\h*#include\h*[<"'']') Then
            $sLine = $aRead[$i]

            ;Merge broken (with _) lines
            If StringRegExp($aRead[$i], '_\h*$') Then
                $sLine = StringRegExpReplace($aRead[$i], '^\h+|[_\h]+$', '')

                While 1
                    $i += 1

                    If $i >= $aRead[0] Then
                        ExitLoop
                    EndIf

                    _AU3_StringStripComments($aRead[$i])
                    $aRead[$i] = StringRegExpReplace($aRead[$i], '[_\h]+$', '')

                    If @extended = 0 Then
                        $sLine &= ' ' & StringStripWS($aRead[$i], 1)
                        ExitLoop
                    EndIf

                    $sLine &= ' ' & StringStripWS($aRead[$i], 1)
                WEnd
            EndIf

            $sSrcRaw &= StringStripWS($sLine, 1) & @CRLF

            ContinueLoop
        EndIf

        ;Get include path
        $sInclude = _AU3_IncludeToPath($aRead[$i], $sScriptDir)

        If Not @error Then
            ;Recursive call for include
            $sSrcRaw = _AU3_StripToRaw($sInclude)
        EndIf
    Next

    Return $sSrcRaw
EndFunc

Func _AU3_IncludeToPath($sInclude, $sScriptDir = @ScriptDir)
    Local $aRegExp, $aRet, $sSYS, $sAU3, $sWorkDir
    Local $iError = 0, $sRet = ''

    $aRegExp = StringRegExp($sInclude, '(?i)^\h*#include\h+(<|"|'')([^>"'']+)(?:>|"|'')\h*(;.*?)?$', 3)

    If UBound($aRegExp) < 2 Then
        Return SetError(1, 0, '')
    EndIf

    $sInclude = $aRegExp[1]

    ;Get AutoIt Include folder
    Local Static $sAutoIt_Incl_Dir = StringRegExpReplace($sAutoItExe, '\\[^\\]+$', '') & '\Include'

    ;Get User Include folders
    Local Static $aUDL = StringRegExp(RegRead('HKCU\Software\AutoIt v3\AutoIt', 'Include'), '([^;]+)(?:;|$)', 3)

    While 1
        ;Check include type 4 (include with full path)
        If Not _WinAPI_PathIsRelative($sInclude) Then
            If FileExists($sInclude) Then
                $sRet = $sInclude
            Else
                $iError = 2
            EndIf

            ExitLoop
        EndIf

        ;Set Current & AutoIt Include file
        $sAU3 = $sScriptDir & '\' & $sInclude
        $sSYS = $sAutoIt_Incl_Dir & '\' & $sInclude

        ;Check include type 1 and 2 (before user includes check)
        If $aRegExp[0] == '<' Then
            If FileExists($sSYS) Then
                $sRet = $sSYS
                ExitLoop
            EndIf
        ElseIf $aRegExp[0] == '"' Or $aRegExp[0] == "'" Then
            If FileExists($sAU3) Then
                $sRet = $sAU3
                ExitLoop
            EndIf
        EndIf

        ;Check include type 3 (search in user includes)
        For $i = 0 To UBound($aUDL) - 1
            $aUDL[$i] &= '\' & $sInclude

            If FileExists($aUDL[$i]) Then
                $sRet = $aUDL[$i]
                ExitLoop 2
            EndIf
        Next

        ;Check include type 1 and 2 (after user includes check)
        If $aRegExp[0] == '<' Then
            If FileExists($sAU3) Then
                $sRet = $sAU3
                ExitLoop
            EndIf
        ElseIf $aRegExp[0] == '"' Or $aRegExp[0] == "'" Then
            If FileExists($sSYS) Then
                $sRet = $sSYS
                ExitLoop
            EndIf
        EndIf

        ;Include file not found
        $iError = 3
        ExitLoop
    WEnd

    If Not $iError Then
        $sWorkDir = @WorkingDir

        If $sWorkDir <> $sScriptDir Then
            FileChangeDir($sScriptDir)
        EndIf

        $sRet = _WinAPI_GetFullPathName($sRet)

        If @error Or $sRet = '' Then
            $iError = 4
        EndIf

        If $sWorkDir <> $sScriptDir Then
            FileChangeDir($sWorkDir)
        EndIf
    Else
        $sRet = ''
    EndIf

    Return SetError($iError, 0, $sRet)
EndFunc

Func _AU3_StringStripCommentBlocks(ByRef $sString)
    Local $aSplit = StringSplit(StringStripCR($sString), @LF)
    Local $iCmntsStart_Count

    $sString = ''

    For $i = 1 To $aSplit[0]
        If StringRegExp($aSplit[$i], '(?i)^\h*#(cs|comments-start)([\h;].*)?$') Then
            $iCmntsStart_Count = 1

            While 1
                If $i + 1 >= $aSplit[0] Then
                    ExitLoop
                EndIf

                $i += 1

                If StringRegExp($aSplit[$i], '(?i)^\h*#(cs|comments-start)([\h;].*)?') Then
                    $iCmntsStart_Count += 1
                    ContinueLoop
                EndIf

                If StringRegExp($aSplit[$i], '(?i)^\h*#(ce|comments-end)([\h;].*)?') Then
                    $iCmntsStart_Count -= 1

                    If $iCmntsStart_Count <= 0 Then
                        ExitLoop
                    EndIf
                EndIf
            WEnd

            ContinueLoop
        EndIf

        $sString &= $aSplit[$i] & @CRLF
    Next
EndFunc

Func _AU3_StringStripComments(ByRef $sString)
    Local $aStrs = StringRegExp($sString, '("[^"]*"|''[^'']*'')', 3)
    Local $sStrs = StringRegExpReplace($sString, '("[^"]*"|''[^'']*'')', '#~_~@~_~#')
    Local $iInStr = StringInStr($sStrs, ';', 2)

    If $iInStr = 0 Then
        Return
    EndIf

    $sString = StringStripWS(StringLeft($sStrs, $iInStr - 1), 2)

    For $i = 0 To UBound($aStrs) - 1
        $sString = StringReplace($sString, '#~_~@~_~#', $aStrs[$i], 1, 2)
    Next
EndFunc
в итоге получаю один файл со всеми вписанными библиотеками. если программа дает ошибку, то открывают этот файл в редакторе и смотрю номер строки
 
Верх