Монитор процесса / диспетчер в VB6 - PullRequest
5 голосов
/ 17 июня 2011

Мне нужно написать небольшое приложение на VB6 для запуска экземпляров другого приложения VB6 и следить за запущенными процессами, но я понятия не имею, как получить информацию о процессах в VB6.Я вижу кое-что из того, что мне нужно, с помощью утилиты tasklist, но я действительно не знаю, как создавать процессы (указав имя процесса или приложения, если это возможно) и получать информацию о процессах из операционной системы.

Это приложение предназначено для работы на компьютере под управлением Windows XP.

Кто-нибудь знает руководство по началу работы или полезную веб-страницу для такого рода вещей?

Ответы [ 4 ]

6 голосов
/ 17 июня 2011

Для этого можно использовать множество функций Windows API. Я бы начал с просмотра EnumProcesses ( VB6 пример и объявление здесь ), которое можно использовать для сбора информации обо всех запущенных процессах. Вы также можете использовать OpenProcess начать опрос Windows о конкретном процессе ( другой пример VB6 ).

Существует также довольно хороший пример на MSDN .

И, конечно, есть CreateProcess ( ссылка AllApi ) или ShellExecute ( AllApi ) для процессов нереста - первый дает вам больший контроль над созданием процесса, а второй - гораздо более простой вызов.

Некоторое время назад был опубликован еще один вопрос с некоторым примером кода.

Другой возможный подход - использовать WMI ( некоторые полезные фрагменты для адаптации ).

Наконец, вот несколько уроков, которые покажут вам, как это сделать (хотя я бы рекомендовал сначала попробовать это самостоятельно:):

Вот некоторые связанные вопросы, хотя вы, вероятно, уже видели их, когда искали этот сайт перед публикацией:

3 голосов
/ 17 июня 2011

Поскольку вы говорите, что другое приложение ** также VB6 **, было бы проще превратить другое приложение в ActiveX exe. Затем вы можете получить ссылки на объекты в другом приложении прямо из вашего первого приложения. COM решает все за вас.

2 голосов
/ 17 июня 2011

Вам не нужно зацикливаться на процессах, просто чтобы получить представление о дочерних процессах, которые вы породили.Функция VB6 Shell () возвращает Идентификатор процесса , который можно использовать для вызова OpenProcess с помощью.CreateProcess дает вам дескриптор напрямую.

Хорошо, вот супер урезанный пример программы на VB6 для порождения и мониторинга программ.Пример закодирован для запуска и многократного перезапуска 3 копий командной оболочки (тривиальный пример дочерней программы).Он также написан, чтобы убить всех работающих детей, когда он завершается, и в большинстве случаев есть лучшие альтернативы для использования.См. Более безопасная альтернатива TerminateProcess () .

Эта демонстрация также сообщает код завершения каждого процесса, который завершается.Вы можете ввести exit 1234 или еще что-нибудь, чтобы увидеть это в действии.

Для создания демонстрации откройте новый проект VB6 с формой.Добавьте многострочное TextBox Text1 и таймер Timer1 (который используется для опроса детей о завершении).Вставьте этот код в форму:

Option Explicit

Private Const SYNCHRONIZE = &H100000
Private Const PROCESS_QUERY_INFORMATION = &H400&
Private Const PROCESS_TERMINATE = &H1&
Private Const WAIT_OBJECT_0 = 0
Private Const INVALID_HANDLE = -1
Private Const DEAD_HANDLE = -2

Private Declare Function CloseHandle Lib "kernel32" ( _
    ByVal hObject As Long) As Long

Private Declare Function GetExitCodeProcess Lib "kernel32" ( _
    ByVal hProcess As Long, _
    ByRef lpExitCode As Long) As Long

Private Declare Function OpenProcess Lib "kernel32" ( _
    ByVal dwDesiredAccess As Long, _
    ByVal bInheritHandle As Long, _
    ByVal dwProcessId As Long) As Long

Private Declare Function TerminateProcess Lib "kernel32" ( _
    ByVal hProcess As Long, _
    ByVal uExitCode As Long) As Long

Private Declare Function WaitForSingleObject Lib "kernel32" ( _
    ByVal hHandle As Long, _
    ByVal dwMilliseconds As Long) As Long

Private Tasks() As String
Private Handles() As Long

Private Sub Form_Load()
    Dim I As Integer

    'We'll run 3 copies of the command shell as an example.
    ReDim Tasks(2)
    ReDim Handles(2)
    For I = 0 To 2
        Tasks(I) = Environ$("COMSPEC") & " /k ""@ECHO I am #" & CStr(I) & """"
        Handles(I) = INVALID_HANDLE
    Next
    Timer1.Interval = 100
    Timer1.Enabled = True
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
    Dim I As Integer

    Timer1.Enabled = False
    DoEvents
    For I = 0 To UBound(Tasks)
        If Handles(I) <> INVALID_HANDLE And Handles(I) <> DEAD_HANDLE Then
            TerminateProcess Handles(I), 666
            CloseHandle Handles(I)
            Handles(I) = DEAD_HANDLE
        End If
    Next
End Sub

Private Sub Timer1_Timer()
    Dim I As Integer
    Dim ExitCode As Long
    Dim Pid As Long

    Timer1.Enabled = False
    For I = 0 To UBound(Tasks)
        If Handles(I) <> INVALID_HANDLE Then
            If WaitForSingleObject(Handles(I), 0) = WAIT_OBJECT_0 Then
                If GetExitCodeProcess(Handles(I), ExitCode) <> 0 Then
                    Text1.SelText = "Task " & CStr(I) & " terminated, " _
                                  & "exit code: " & CStr(ExitCode) _
                                  & ", restarting task." _
                                  & vbNewLine
                Else
                    Text1.SelText = "Task " & CStr(I) & " terminated, " _
                                  & "failed to retrieve exit code, error " _
                                  & CStr(Err.LastDllError) _
                                  & ", restarting task." _
                                  & vbNewLine
                End If
                CloseHandle Handles(I)
                Handles(I) = INVALID_HANDLE
            End If
        End If
        If Handles(I) = INVALID_HANDLE Then
            Pid = Shell(Tasks(I), vbNormalFocus)
            If Pid <> 0 Then
                Handles(I) = OpenProcess(SYNCHRONIZE _
                                      Or PROCESS_QUERY_INFORMATION _
                                      Or PROCESS_TERMINATE, 0, Pid)
                If Handles(I) <> 0 Then
                    Text1.SelText = "Task " & CStr(I) & " started." _
                                  & vbNewLine
                Else
                    Text1.SelText = "Task " & CStr(I) _
                                  & ", failed to open child process." _
                                  & vbNewLine
                    Handles(I) = DEAD_HANDLE
                End If
            Else
                Text1.SelText = "Task " & CStr(I) _
                              & ", failed to Shell child process." _
                              & vbNewLine
                Handles(I) = DEAD_HANDLE
            End If
        End If
    Next
    Timer1.Enabled = True
End Sub

Надеюсь, это поможет ответить на вопрос.

0 голосов
/ 17 июня 2011

что-то более простое будет использовать сокеты.

Запускает сервер приложений, а на вашем клиенте реализуется связь с вашим сервером. С этим вы обеспечите связь.

Хорошо, я говорю. потому что я не то, что вы пытаетесь сделать

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

...