VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)
首页 - 经验之谈 - 用VB开发进程管理软件
发表评论(0)作者:四川 虞东海, 平台:VB6.0+Win98, 阅读:12106, 日期:2000-11-22
用VB开发进程管理软件

     进程管理在Windows中是一个比较重要的内容,由于每一个正在运行的程序(包括Windows的后台程序和动态链接库)都对应有各自的进程,通过对进程的管理可以防止一些非法程序(如特洛伊木马程序)的运行,但是Windows的任务管理器(就是按ALT+CTRL+DEL后出现的那个东东)虽然能够中止进程,不过它的进程列表里面已经屏蔽了某些与系统有关的进程,现在有的特洛伊木马(如冰河)在编程时将自己注册为系统服务,因此通过Windows的任务管理器并不能中止它的进程;而Windows的系统信息工具msinfo32.exe虽然能够列出系统中所有的进程,但是并不能中止进程,所以也是于事无补。
为此我们可以自己编写一个进程管理软件,首先,它要能够列出系统中的所有进程,其次也要能够中止系统中任意一个进程(当然有些进程中止后将有可能导致死机)。
编程思路:列出系统进程一般的方法是通过调用一组ToolHelp32函数,该组函数存在于kernel32.dll链接库中,它有许多功能,而枚举系统中的进程只是它众多功能中的一项。下面是要用到的几个关于进程的API函数:CreateToolHelpSnapshot()、ProcessFirst()、ProcessNext()。不知道是什么原因,这么重要的函数微软居然并没有将其录入到VB的API文本浏览器中,因此我们只好手工将其录入了,下面是声明:
Public Declare Function CreateToolhelpSnapshot Lib "kernel32" Alias "CreateToolhelp32Snapshot" (ByVal lFlags As Long,ByVal lProcessID As Long) As Long
Public Declare Function ProcessFirst Lib "kernel32" Alias "Process32First" (ByVal hSnapShot As Long,uProcess As PROCESSENTRY32) As Long
Public Declare Function ProcessNext Lib "kernel32" Alias "Process32Next" (ByVal hSnapShot As Long,uProcess As PROCESSENTRY32) As Long  
此外还需要定义一个PROCESSENTRY32结构,这个结构中包含有有关系统中进程的某些信息,同样在VB中的API文本浏览器里也没有录入。
Public Type PROCESSENTRY32
dwSize As Long
cntUsage As Long
th32ProcessID As Long
(上接三十三版)th32DefaultHeapID As Long
th32ModuleID As Long
cntThreads As Long
th32ParentProcessID As Long
pcPriClassBase As Long
dwFlags As Long
szExeFile As String*MAX_PATH
End Type
下面是列出系统进程的步骤:    
1.用CreateToolHelpSnapshot()函数来创建系统中进程信息的“快照”,该函数返回一个句柄(该句柄将在下面的函数中得到应用);
2.用ProcessFirst()函数从以上“快照”中获取进程,该函数有两个参数,第一个是第一步中函数返回的句柄,第二个是指向PROCESSENTRY32结构的指针,当系统中还有其它进程时,该函数返回true;
3.用ProcessNext()函数从“快照”中不断获取进程,直到它返回false为止;
4.用CloseHandle()函数关闭第一步中的句柄。   
关闭进程也是一个值得讨论的问题,传统的方法是用GetWindow来查找窗口句柄,再利用GetWindowText来获得窗口的标题,然后利用SendMessage函数发送WM_CLOSE消息来关闭该程序。不过这种方法有很大的缺陷:首先是有的窗口是没有标题栏的,这样的程序是无法通过该方法关闭的;其次,这种方法对动态链接库也是无法关闭的。在这里我们可以充分利用PROCESSENTRY32结构,它里面有一个th32ProcessID成员,通过TerminateProcess()函数就可以关闭进程。
    下面是编程的具体步骤:
    1.新建一工程,在窗体Form1中添加一个ListView控件,二个CommandButton;     
2.按如下设置控件:Command1.Caption="查看进程";Command2.Caption="中止进程";lvw.width=5400
3.在“工程”中选择“添加模块”,加入上面的函数和结构声明及以下内容:
Public Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long,ByVal uExitCode As Long) As Long
Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long,ByVal bInheritHandle As Long,ByVal dwProcessId As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Public Const TH32CS_SNAPPROCESS=&H2
Public Const TH32CS_SNAPheaplist=&H1
Public Const TH32CS_SNAPthread=&H4
Public Const TH32CS_SNAPmodule=&H8Public Const TH32CS_SNAPall=TH32CS_SNAPPROCESS+TH32CS_SNAPheaplist+TH32CS_SNAPthread+TH32CS_SNAPmodule
Public Const MAX_PATH As Integer=260          
4.添加代码:
Private Sub command1_Click()
Dim i As Long
Dim proc As PROCESSENTRY32
Dim snap As Long
Dim exename As String
lvw.ListItems.Clear         注释:清空所有内容
snap=Create Toolhelp Snapshot(TH32CS-SNAPall,0)    注释:获得进程“快照”的句柄
proc.dwSize=Len(proc)
theloop=ProcessFirst(snap,proc)          注释:获取第一个进程,并得到其返回值
i=0
While theloop<>0        注释:当返回值非零时继续获取下一个进程
exename=proc.szExeFile
ret=lvw.ListItems.Add(,"first" & CStr(i),exename)   注释:将进程名添加到第一项中
lvw.ListItems("first" & CStr(i)).SubItems(1)=proc.th32ProcessID  注释:将进程ID添加到第二项中
i=i+1
theloop=ProcessNext(snap,proc)
Wend
CloseHandle snap       注释:关闭进程“快照”句柄
End Sub
Private Sub Command2_Click()
Dim i As Long
hand=OpenProcess(process_terminate,True,CLng(lvw.SelectedItem.SubItems(1)))   注释:获取进程句柄
TerminateProcess hand,0       注释:关闭进程
Call command1_Click         注释:调用查看进程来刷新进程列表
End Sub
Private Sub Form_Load()
Dim header As ColumnHeader
lvw.View = lvwReport
lvw.ColumnHeaders.Clear
Set header=lvw.ColumnHeaders.Add(,"first","进程",4000)    注释:设置ListView中项目的宽度,读者也可自行设置
Set header=lvw.ColumnHeaders.Add(,"second","ID",1400)
lvw.Refresh
End Sub
程序的运行界面如图所示。
程序在Windows98中文版、VB6.0中文企业版下运行通过。需要说明的是由于Windows95/98与WinNT中列出系统进程的Windows API函数不同,所以以上程序只能在Win95/98中运行,不能在WinNT及Win2000下运行。(四川 虞东海)