VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)
首页 - 经验之谈 - ToolHelp32 函数揭密
发表评论(0)作者:四川 虞东海, 平台:VB6.0+Win98, 阅读:11707, 日期:2001-03-18
ToolHelp32 函数揭密




     拙稿《用VB开发进程管理软件》在《家用电脑》第44期(2000年)中刊出后,由于在文中使用了ToolHelp32函数中的CreateToolHelpSnapshot() 、ProcessFirst()和ProcessNext()等函数,因篇幅所限,并没有对ToolHelp32函数的用法作详细的说明,于是有读者发信给笔者,希望笔者能对该函数组的用法作一详细的说明。因此笔者想利用《家用电脑》的一角向读者交待一下这个问题,并向所有关心和支持我的读者及编辑致敬!
    在拙稿中已作过说明,ToolHelp32函数是一组寄存在Kernel32.dll中的Windows API函数,它能够通过快照(Snapshot)中获得驻留在系统内存中的进程表、线程表、模块表和堆表,并提供函数来枚举系统中的进程、线程以及模块信息,因此是一个非常重要的函数组。
    1.ToolHelp32中的函数
    常用的ToolHelp32中的函数除了CreateToolHelpSnapshot() 、ProcessFirst()和ProcessNext()以外主要有Heap32First()、 Heap32Next()、 Heap32ListFirst()、 Heap32ListNext()(以上用来枚举进程分配的堆的信息)、Module32First()、Module32Next()(以上用来枚举系统中已加载的模块的信息)、Thread32First()、Thread32Next()(以上用来枚举系统中正在执行的线程)。这些函数的声明如下:
    Private Declare Function Module32First Lib "kernel32" (ByVal hSnapshot As Long,lppe As MODULEENTRY32) As Long
    Private Declare Function Module32Next Lib "kernel32" (ByVal hSnapshot As Long,lppe As MODULEENTRY32) As Long
    Private Declare Function Thread32First Lib "kernel32" (ByVal hSnapshot As Long,lppe As THREADENTRY32) As Long
    Private Declare Function Thread32Next Lib "kernel32" (ByVal hSnapshot As Long,lppe As THREADENTRY32) As Long
    Heap32First()、Heap32Next()等函数由于不常用,其声明省略。
    2.ToolHelp32中的结构
    ToolHelp32中的结构除了已介绍的PROCESSENTRY32外,还有MODULEENTRY32、THREADENTRY32、HEAPENTRY32、HEAPLIST32等结构,其声明如下:
    Private Type MODULEENTRY32
    dwsize As Long
    th32ModuleID As Long
    th32ProcessID As Long
    GlblcntUsage As Long
    ProccntUsage As Long
    modBaseAddr As Byte
    modBaseSize As Long
    hModule As Long
    szModule As String * 256
    szExePath As String * 1024
    End Type
    Private Type THREADENTRY32
    dwsize As Long
    cntusage As Long
    th32threadID As Long
    th32OwnerProcessID As Long
    tpBasePri As Long
    tpDeltaPri As Long
    dwFlags As Long
    End Type
    (HEAPENTRY32、HEAPLIST32等结构声明省略)
    3.ToolHelp32中函数的用法:
    我在拙文中已详细讲述过ProcessFirst()和ProcessNext()等函数,其实,ToolHelp32中其它函数的用法几乎是大同小异,也同样是“四部曲”:
    1)用CreateToolHelp32Snapshot()函数创建信息“快照”;
    2)用Module32First()或Thread32First()函数来获取第一个模块或线程;
    3)用Module32Next()或Thread32Next()函数不断获取模块或线程;
    4)用CloseHandle()函数关闭句柄。
    4.应用示例
    为了更好地理解ToolHelp32的应用,我们可以通过一示例程序来演示如何利用ToolHelp32函数来获得系统中的进程、线程及已加载的模块:
    新建一工程,在窗体中加入一个ListBox控件,三个CommandButton控件,其中Command1.Caption="进程", Command2.Caption="线程",Command3.Caption="模块"。
    请自行在窗体的通用部分加入以上Windows API函数的声明及结构的声明,有关ProcessFirst()等函数和结构的声明请参阅第44期,同时还需声明部分常数,也请读者自行参阅第44期。
    下面是程序部分:
    Private Sub Command2_Click()
    Dim th As THREADENTRY32
    Dim l As Long
    List1.Clear
    l=CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0)      获得线程快照句柄
    th.dwsize=Len(th)     初始化结构的大小,否则ToolHelp32将不能正确调用
    If Thread32First(l,th) Then
    Do
    List1.AddItem Hex(th.th32OwnerProcessID)    将创建该线程的进程标识符(转化为16进制)加入ListBox
    Loop Until Thread32Next(l,th)=0        当返回0时说明已找到最后一个线程
    End If
    CloseHandle (l)        关闭句柄
    End Sub
    
    Private Sub Command3_Click()
      Dim pr As PROCESSENTRY32
      Dim lp As Long
      Dim mo As MODULEENTRY32
      Dim lm As Long
      
      List1.Clear
      lp=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0)      获得进程快照句柄
      If lp>0 Then
       pr.dwsize=Len(pr) 初始化结构pr的大小
        If Process32First(lp,pr) Then
          Do
           获得模块快照句柄
             lm=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,pr.th32ProcessID)
            If lm>0 Then
              mo.dwsize=Len(mo)       初始化结构mo的大小
              If Module32First(lm,mo) Then
                Do
                  List1.AddItem mo.szExePath    将加载模块的路径加入ListBox
                Loop Until  Module32Next(lm,mo)=0
              End If
              CloseHandle (lm)   关闭模块快照句柄
            End If
          Loop Until Process32Next(lp,pr)=0
        End If
        CloseHandle (lp)   关闭进程快照句柄
      End If
    End Sub
    由于获得系统进程的方法在拙文《用VB开发进程管理软件》中已有叙述,故在此省略,以上程序的运行界面如图1、2所示,在Windows98中文版Visual Basic6.0中文企业版下通过。(四川 虞东海)