Мониторинг процессов, чтобы увидеть, не произошли ли они в vb6 - PullRequest
1 голос
/ 25 ноября 2008

У меня есть программа, которая часто дает сбой, когда я сплю, и мне нужно, чтобы она работала. Поэтому я подумал, что могу написать приложение vb6, которое отслеживает список процессов, если что-то пропадет, оно перезапустит его. Кто-нибудь знает легкий путь?

Ответы [ 4 ]

3 голосов
/ 05 декабря 2008

Вы можете использовать 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

код функции немного длинный, но его вызов - небольшая функция, вы можете использовать его, если хотите немного протестировать:)

2 голосов
/ 25 ноября 2008

Использование WMI .

Если вы застряли с VB6, поищите в Интернете WMI + VB6.
В противном случае, интерфейс C # и WMI гораздо проще.

0 голосов
/ 27 ноября 2008

Я использую программу, которая запускает другие программы. Таким образом, вы можете опрашивать дескриптор процесса, чтобы увидеть, запущено ли приложение. Если нет, вы можете запустить его снова. Это требует программирования API.

0 голосов
/ 25 ноября 2008

Я использовал запланированное задание (выполняется каждые 10 минут), запуская cmd-файл со следующим содержимым:

tasklist | find "myapp.exe"> nul || C: \ mypath \ myapp.exe

Вы можете выполнить такой командный файл из оболочки VB6 или просто использовать Task Scheduler:)

...