Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   AutoIt (http://forum.oszone.net/forumdisplay.php?f=103)
-   -   [решено] как отследить падение процесса, если их запущено несколько? (http://forum.oszone.net/showthread.php?t=180551)

diamonster 14-07-2010 12:37 1453114

как отследить падение процесса, если их запущено несколько?
 
мне нужно написать простейший watchdog. если процесс не обнаружен - запустить.
дело усложняется тем, что одинаковых процессов должно быть запущено несколько, просто из разных папок, с разными конфигами.
ProcessExists($proc) отслеживает только имя процесса, соответственно если отвалился один из трёх, то эта функция никак не реагирует.
есть ли какое-то решение проблемы?

Creat0R 14-07-2010 13:03 1453130

Можно искать в списке процессов по исполняемому пути к процессу:

Код:

$aRun_Processes = StringSplit(@SystemDir & "\Notepad.exe" & "|" & @WindowsDir & "\Regedit.exe", "|")

HotKeySet("{ESC}", "_Quit")

While 1
    Sleep(1000)
    $aProcList = _ProcessListEx()

    For $i = 1 To $aRun_Processes[0]
        $bFound = False

        For $j = 1 To $aProcList[0][0]
            If $aProcList[$j][2] = $aRun_Processes[$i] Then
                $bFound = True
            EndIf
        Next

        If Not $bFound Then
            Run($aRun_Processes[$i])
        EndIf
    Next
WEnd

Func _Quit()
    Exit
EndFunc

Func _ProcessListEx($sResourceName="", $sInResString="", $iWholeWord=1)
    Local $aProcList = ProcessList()
    Local $hKernel32_Dll = DllOpen('Kernel32.dll'), $hPsapi_Dll = DllOpen('Psapi.dll')
    Local $aOpenProc, $aProcPath, $sFileVersion, $aRet_List[1][1]

    If $hKernel32_Dll = -1 Then Return SetError(1, 0, '')

    If $hPsapi_Dll = -1 Then $hPsapi_Dll = DllOpen(@SystemDir & '\Psapi.dll')
    If $hPsapi_Dll = -1 Then $hPsapi_Dll = DllOpen(@WindowsDir & '\Psapi.dll')
    If $hPsapi_Dll = -1 Then Return SetError(2, 0, '')

    Local $vStruct      = DllStructCreate('int[1024]')
    Local $pStructPtr  = DllStructGetPtr($vStruct)
    Local $iStructSize  = DllStructGetSize($vStruct)

    For $i = 1 To UBound($aProcList)-1
        $aOpenProc = DllCall($hKernel32_Dll, 'hwnd', 'OpenProcess', _
            'int', BitOR(0x0400, 0x0010), 'int', 0, 'int', $aProcList[$i][1])

        If Not IsArray($aOpenProc) Or Not $aOpenProc[0] Then ContinueLoop

        DllCall($hPsapi_Dll, 'int', 'EnumProcessModules', _
            'hwnd', $aOpenProc[0], _
            'ptr', $pStructPtr, _
            'int', $iStructSize, _
            'int*', 0)

        $aProcPath = DllCall($hPsapi_Dll, 'int', 'GetModuleFileNameEx', _
            'hwnd', $aOpenProc[0], _
            'int', DllStructGetData($vStruct, 1), _
            'str', '', _
            'int', 2048)

        DllCall($hKernel32_Dll, 'int', 'CloseHandle', 'int', $aOpenProc[0])

        If Not IsArray($aProcPath) Or StringLen($aProcPath[3]) = 0 Then ContinueLoop

        $sFileVersion = FileGetVersion($aProcPath[3], $sResourceName)

        If $sResourceName = "" Or $sFileVersion = $sInResString Or _
            ($iWholeWord = 0 And StringInStr($sFileVersion, $sInResString)) Then

            $aRet_List[0][0] += 1
            ReDim $aRet_List[$aRet_List[0][0]+1][3]
            $aRet_List[$aRet_List[0][0]][0] = $aProcList[$i][0]    ;Process Name
            $aRet_List[$aRet_List[0][0]][1] = $aProcList[$i][1]    ;PID (Process ID)
            $aRet_List[$aRet_List[0][0]][2] = $aProcPath[3]        ;Process File Path
        EndIf
    Next

    DllClose($hKernel32_Dll)
    DllClose($hPsapi_Dll)

    If $aRet_List[0][0] < 1 Then Return SetError(3, 0, '')
    Return $aRet_List
EndFunc


diamonster 14-07-2010 14:00 1453172

Отлично! Спасибо, всё работает.


Время: 17:30.

Время: 17:30.
© OSzone.net 2001-