У меня есть программа, которая довольно часто дает сбой, пока я сплю, и мне нужно, чтобы она работала. Поэтому я подумал, что могу написать приложение vb6, которое отслеживает список процессов, и если что-то исчезнет, оно перезапустит его. Кто-нибудь знает простой способ?
Мониторинг процессов, чтобы увидеть, не упали ли они в vb6
Ответы (4)
Вы можете использовать EnumProcesses, чтобы перечислить все процессы в система в тот момент, когда вы работаете, вы можете использовать это объявление, чтобы использовать ее
Public Declare Function EnumProcesses Lib "psapi.dll" ( _
ByRef idProcess As Long, ByVal cb As Long, _
ByRef cbNeeded As Long) As Long
Перед его использованием вы должны определить массив Long для передачи в качестве аргумента EnumProcesses с достаточным пространством для чтения всех идентификаторов процессов. Вы можете вызвать EnumProcesses дважды, чтобы узнать, насколько большим должен быть этот массив. После второго вызова вы можете начать перебирать этот массив и открывать процессы, получая таким образом дескриптор, который используется соответствующим образом, может сообщить вам имя исполняемого файла процесса и сравнить эти данные с именем исполняемого файла, который вы ищете. В противном случае, если вы ищете DLL, например, вы можете EnumProcessModules для этого процесса обрабатывать поиск каждого запущенного процесса для DLL, которую вы ищете. объявление EnumProcessModules это
Public Declare Function EnumProcessModules Lib "psapi.dll" ( _
ByVal hProcess As Long, ByRef lphModule As Long, _
ByVal cb As Long, ByRef cbNeeded As Long) As Long
и вероятный код, который вам понадобится, будет примерно таким
Option Explicit
Private Declare Function OpenProcess Lib "Kernel32.dll" ( _
ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, _
ByVal dwProcId As Long) As Long
Private Declare Function EnumProcesses Lib "psapi.dll" ( _
ByRef lpidProcess As Long, ByVal cb As Long, _
ByRef cbNeeded As Long) As Long
Private Declare Function GetModuleFileNameExA Lib "psapi.dll" ( _
ByVal hProcess As Long, ByVal hmodule As Long, _
ByVal moduleName As String, ByVal nSize As Long) As Long
Private Declare Function EnumProcessModules Lib "psapi.dll" ( _
ByVal hProcess As Long, ByRef lphModule As Long, _
ByVal cb As Long, ByRef cbNeeded As Long) As Long
Private Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Const PROCESS_ALL_ACCESS As Long = &H1F0FFF
Public Function IsModuleRunning(ByVal theModuleName As String) As Boolean
Dim aProcessess(1 To 1024) As Long ' up to 1024 processess?'
Dim bytesNeeded As Long
Dim i As Long
Dim nProcesses As Long
Dim hProcess As Long
Dim found As Boolean
EnumProcesses aProcessess(1), UBound(aProcessess), bytesNeeded
nProcesses = bytesNeeded / 4
For i = 1 To nProcesses
hProcess = OpenProcess(PROCESS_ALL_ACCESS, False, aProcessess(i))
If (hProcess) Then
Dim hmodule(1 To 1024) As Long ' no more than 1024 modules per process?'
bytesNeeded = 0
If EnumProcessModules(hProcess, hmodule(1), 1024 * 4, bytesNeeded) Then
Dim nModules As Long
Dim j As Long
Dim moduleName As String
moduleName = Space(1024) ' module name should have less than 1024 bytes'
nModules = bytesNeeded / 4
For j = 1 To nModules
Dim fileNameLen As Long
fileNameLen = GetModuleFileNameExA(hProcess, hmodule(j), moduleName, 1024)
moduleName = Left(moduleName, fileNameLen)
If Right(LCase(moduleName), Len(theModuleName)) = LCase(theModuleName) Then
found = True
Exit For
End If
Next
End If
End If
CloseHandle hProcess
If found Then Exit For
Next
IsModuleRunning = found
End Function
Private Sub Form_Load()
MsgBox IsModuleRunning("explorer.exe")
End Sub
Код функции немного длинный, но вызов его — это небольшая функция, вы можете использовать его, если хотите немного протестировать :)
Используйте WMI.
Если вы застряли с VB6, выполните поиск Интернет для WMI+VB6.
В противном случае гораздо проще связать C# и WMI.
Я использую программу, которая запускает другие программы. Таким образом, вы можете опросить дескриптор процесса, чтобы узнать, работает ли приложение. Если нет, вы можете запустить его снова. Это требует программирования API.
Я использовал запланированное задание (выполняется каждые 10 минут), запуская файл cmd со следующим содержимым:
tasklist |find "myapp.exe" >nul || c:\mypath\myapp.exe
Вы можете выполнить такой командный файл из оболочки VB6 или просто использовать планировщик заданий :)