VB6中的进程监视/调度程序

时间:2011-06-17 11:15:13

标签: vb6 windows-xp

我需要在VB6中编写一个小应用程序来运行另一个VB6应用程序的实例并密切关注正在运行的进程,但我不知道如何在VB6中获取进程信息。我可以通过tasklist实用程序看到我需要的一些内容,但我真的不知道如何创建进程(如果可能,指定进程或应用程序名称)并从操作系统中获取有关进程的信息。

此应用程序将在Windows XP计算机上运行。

有没有人知道有关此类内容的入门教程或有用的网页?

4 个答案:

答案 0 :(得分:6)

您可以使用许多Windows API函数来执行此操作。我首先看一下EnumProcessesVB6 example and declaration here),它可以用来收集有关所有正在运行的进程的信息。您也可以使用OpenProcess  开始询问有关特定进程的Windows(another VB6 example)。

还有fairly nice example on MSDN

当然,产生过程有CreateProcessAllApi link)或ShellExecuteAllApi) - 前者可让您更好地控制过程的创建虽然后者是一个更简单的电话。

There was another question posted about this a while back with some example code.

另一种可能的方法是使用WMIsome useful snippets to adapt)。

最后,这里有一些教程向您展示如何做到这一点(我建议您先尝试自己尝试:):

以下是一些相关问题,尽管您在发布之前搜索过这个网站时可能已经看到了这些问题:

答案 1 :(得分:3)

既然你说其他应用程序也是VB6 **,那么将其他应用程序变成ActiveX exe会更容易。然后,您可以直接从第一个应用程序获取对其他应用程序中对象的引用。 COM为您解决了这一切。

答案 2 :(得分:2)

您不需要为了处理您生成的子进程而处理进程。 VB6 Shell()函数返回一个进程ID ,可用于调用OpenProcessCreateProcess直接为您提供句柄。

好的,这是一个超级精简的VB6程序示例,用于生成和监视程序。该示例被编码为启动并重复重启命令shell的3个副本(普通样本子程序)。它也被编写为终止任何正在运行的孩子,并且在大多数情况下有更好的替代方案。请参阅A Safer Alternative to 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

希望这有助于回答这个问题。

答案 3 :(得分:0)

更简单的东西会使用套接字。

启动您的应用服务器,并在您的客户端上实现与您的服务器的通信。有了它,你将提供相互通信。

好吧,我说。因为我不是你想做的事情

很抱歉,只有当您的客户在内部完成后,您才可以选择添加更改