我需要在VB6中编写一个小应用程序来运行另一个VB6应用程序的实例并密切关注正在运行的进程,但我不知道如何在VB6中获取进程信息。我可以通过tasklist
实用程序看到我需要的一些内容,但我真的不知道如何创建进程(如果可能,指定进程或应用程序名称)并从操作系统中获取有关进程的信息。
此应用程序将在Windows XP计算机上运行。
有没有人知道有关此类内容的入门教程或有用的网页?
答案 0 :(得分:6)
您可以使用许多Windows API函数来执行此操作。我首先看一下EnumProcesses
(VB6 example and declaration here),它可以用来收集有关所有正在运行的进程的信息。您也可以使用OpenProcess
开始询问有关特定进程的Windows(another VB6 example)。
还有fairly nice example on MSDN。
当然,产生过程有CreateProcess
(AllApi link)或ShellExecute
(AllApi) - 前者可让您更好地控制过程的创建虽然后者是一个更简单的电话。
There was another question posted about this a while back with some example code.
另一种可能的方法是使用WMI(some useful snippets to adapt)。
最后,这里有一些教程向您展示如何做到这一点(我建议您先尝试自己尝试:):
以下是一些相关问题,尽管您在发布之前搜索过这个网站时可能已经看到了这些问题:
答案 1 :(得分:3)
既然你说其他应用程序也是VB6 **,那么将其他应用程序变成ActiveX exe会更容易。然后,您可以直接从第一个应用程序获取对其他应用程序中对象的引用。 COM为您解决了这一切。
答案 2 :(得分:2)
您不需要为了处理您生成的子进程而处理进程。 VB6 Shell()函数返回一个进程ID ,可用于调用OpenProcess
。 CreateProcess
直接为您提供句柄。
好的,这是一个超级精简的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)
更简单的东西会使用套接字。
启动您的应用服务器,并在您的客户端上实现与您的服务器的通信。有了它,你将提供相互通信。
好吧,我说。因为我不是你想做的事情很抱歉,只有当您的客户在内部完成后,您才可以选择添加更改