Как отследить зависание чужой программы, когда в диспетчере задач состояние "не отвечает" - VB
Формулировка задачи:
Практическая значимость: перезапуск сервера.
Еще нашел на языке AutoIT (там API используется):
Желательно без использования WIN.API.
Нашел на WMI, но пока не разобрал логику работы:
Листинг программы
- strComputer = "."
- Set objWMIService = GetObject("winmgmts:" _
- & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
- Set objWMIRestart = GetObject("winmgmts:" _
- & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2:Win32_Process")
- Set colMonitoredProcesses = objWMIService. _
- ExecNotificationQuery("select * from __InstanceDeletionEvent " _
- & " Within 5 Where TargetInstance isa 'Win32_Process'")
- Do
- Set objLatestProcess = colMonitoredProcesses.NextEvent
- If objLatestProcess.TargetInstance.Name = "GV600.exe" Then
- WScript.Sleep(2000)
- intReturn = objWMIRestart.Create("c:\GV600\GV600.exe", null, null)
- End If
- Loop
Листинг программы
- $hWin = WinGetHandle('My Window')
- If _WinAPI_IsHungAppWindow($hWin) Then
- MsgBox(48, '', 'Окно зависло')
- EndIf
- Func _WinAPI_IsHungAppWindow($hWnd)
- Local $aRet = DllCall('user32.dll', 'int', 'IsHungAppWindow', 'hwnd', $hWnd)
- If @error Then
- Return SetError(1, 0, 0)
- EndIf
- Return $aRet[0]
- EndFunc
Актуально.
1. Как вообще интерпретируется понятие "зависание программы" с точки зрения низкоуровневого программирования и какие бывают причины?
2. Есть понятие "временного зависания", когда ОС не может дождаться некоторого установленного по-умолчанию тайм-аута ответа от запущенной команды. Есть ли здесь что-то общее с предыдущим пунктом?
3. По каким признакам ОС определяет, что процесс "завис" ?
4. Как наиболее просто симмитировать "зависание" своей программы?
Решение задачи: «Как отследить зависание чужой программы, когда в диспетчере задач состояние "не отвечает"»
textual
Листинг программы
- @echo off&:: by Alex Dragokas -05.01.13-
- SetLocal EnableDelayedExpansion EnableExtensions
- ::Name of a watching processes (separeted by ,)
- Set ProcNames=example.exe,example2.exe
- ::Set ProcNames=iw5mp_server.exe
- ::Delay (ms.) before the next check
- Set /A DelayNewCheck=5000
- ::Delay (ms.) before starting a process after shutting down because of "not responding" status
- Set DelayStartProcess=3000
- ::Setting Priority of Application to Run with (1 to 6):
- ::1 - LOW, 2 - BELOWNORMAL, 3 - NORMAL, 4 - ABOVENORMAL, 5 - HIGH, 6 - REALTIME
- Set Priority=3
- ::Start the process in Minimize mode? (1 - Yes, 2 - No)
- Set Minimize=1
- ::The time (ms.) while we checking if a process really not responding all this time
- Set /A BugTime=10000
- ::How many times we make a series of chekings (during %BugTime%)
- Set /A BugChecks=10
- Set /A BugIntervals=%BugChecks% - 1
- Set /A BugIntervalsDelay=%BugTime% / %BugIntervals%
- Call :PriorityEnum %Priority% Priority
- if %Minimize%==1 (set Minimize=/MIN ) else (set Minimize=)
- Set ProcNames="%ProcNames:,=" "%"
- :begin
- For %%A in (%ProcNames%) do call :WatchSingleProcess "%%~A"
- Call :Delay %DelayNewCheck%
- Goto :begin
- :WatchSingleProcess %1-Name_of_Process
- Set Process=%~1
- Call :IsResponding "%Process%"
- Set PID=%errorlevel%
- if %PID% neq 0 (
- <nul set /p test=Found Bug in "%Process%" PID=%PID%
- for /L %%C in (1,1,%BugChecks%) do (
- Call :IsResponding "%Process%"
- if !errorlevel! neq 0 (
- <nul set /p test=.
- if %%C==%BugChecks% (Call :Restart "%PID%" "%Process%"& Exit /B)
- Call :Delay %BugIntervalsDelay%
- ) else (
- Echo Waked up
- Exit /B
- )
- )
- )
- Exit /B
- :Delay %1-msec.
- ping 192.168.254.254 -n 2 -w %~1 > nul
- Exit /B
- :IsResponding %1-ProcessName
- For /f "tokens=1,2 delims=," %%A in (
- 'tasklist /FI "IMAGENAME eq %~1" /FI "STATUS eq NOT RESPONDING" /FO CSV /NH') do (
- if /i "%%~A"=="%~1" Exit /B %%~B
- )
- Exit /B 0
- :Restart %1-Proccess_PID %2-Process_Name
- Echo ShutDown
- ::Getting the Process' FullName (with Path)
- for /f "tokens=2 delims==" %%A in (
- 'wmic path win32_process where ^(ProcessID^=%~1 and name^="%~2"^) get "CommandLine" /value^|find "CommandLine"'
- ) do (Set ProcessFullName=%%A)
- taskkill /F /PID %~1
- Call :Delay %DelayStartProcess%
- start "" %Minimize%/%Priority% %ProcessFullName%
- Echo %ProcessFullName% started successfully.
- Exit /B
- :PriorityEnum %1-Constant %2-var.name
- if %~1==1 Set %~2=LOW
- if %~1==2 Set %~2=BELOWNORMAL
- if %~1==3 Set %~2=NORMAL
- if %~1==4 Set %~2=ABOVENORMAL
- if %~1==5 Set %~2=HIGH
- if %~1==6 Set %~2=REALTIME
- Exit /B
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д