zen_z的专栏

开始学习的点点滴滴

CreateToolhelp32Snapshot

CreateToolhelp32Snapshot

 

  CreateToolhelp32Snapshot函数为指定的进程、进程使用的堆[HEAP]、模块[MODULE]、线程[THREAD])建立一个快照[snapshot]。   
HANDLE WINAPI CreateToolhelp32Snapshot(   DWORD dwFlags,   DWORD th32ProcessID   );   
参数:   dwFlags   [输入]指定快照中包含的系统内容,这个参数能够使用下列数值(常量)中的一个或多个。   TH32CS_INHERIT - 声明快照句柄是可继承的。   
TH32CS_SNAPALL - 在快照中包含系统中所有的进程和线程。   
TH32CS_SNAPHEAPLIST - 在快照中包含在th32ProcessID中指定的进程的所有的堆。   
TH32CS_SNAPMODULE - 在快照中包含在th32ProcessID中指定的进程的所有的模块。   
TH32CS_SNAPPROCESS - 在快照中包含系统中所有的进程。   
TH32CS_SNAPTHREAD - 在快照中包含系统中所有的线程。   
Const TH32CS_SNAPHEAPLIST = &H1   
Const TH32CS_SNAPPROCESS = &H2   
Const TH32CS_SNAPTHREAD = &H4   
Const TH32CS_SNAPMODULE = &H8   
Const TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE)   
Const TH32CS_INHERIT = &H80000000   
th32ProcessID   [输入]指定将要快照的进程ID。如果该参数为0表示快照当前进程。该参数只有在设置了TH32CS_SNAPHEAPLIST,TH32CS_SNAPMODULE,TH32CS_SNAPALL后才有效,在其他情况下该参数被忽略,所有的进程都会被快照。   
返回值:   调用成功,返回快照的句柄,调用失败,返回INVALID_HANDLE_VALUE 。   
备注:   使用GetLastError函数查找该函数产生的错误状态码。   
要删除快照,使用CloseHandle函数   
delphi使用实例:   
uses TLHelp32;   
procedure TForm1.Button1Click(Sender: TObject);   
var   ProcessName: string;   
ProcessID: integer;   
ListLoop: Boolean;   
FsnapShotHandle: Thandle;   
FProcessEntry32: TProcessEntry32;   
begin   Fsnapshothandle := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0);   FProcessEntry32.dwsize := SizeOF(FProcessEntry32);   
Listloop := Process32First(FSnapshotHandle, FProcessEntry32);   
while Listloop do begin   
ProcessName := FprocessEntry32.szExeFile;   
ProcessID := FProcessEntry32.th32ProcessID;   // 我写到列表框中了,你可以根据需要自己改   
listbox1.Items.Add('Process NAME:' + ProcessNAme);   
ListLoop := Process32Next(FSnapshotHandle, FprocessEntry32);   
end;   
end;   
/////////////////////////////////////////////////////////
VB使用实例:   Private Type PROCESSENTRY32   dwSize As Long   cntUseage As Long   th32ProcessID As Long   th32DefaultHeapID As Long   th32ModuleID As Long   cntThreads As Long   th32ParentProcessID As Long   pcPriClassBase As Long   swFlags As Long   szExeFile As String * 1024   End Type   Private sub demo()   Dim MySnapHandle As Long   Dim ProcessInfo As PROCESSENTRY32   MySnapHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)   ProcessInfo.dwSize = Len(ProcessInfo)   If Process32First(MySnapHandle, ProcessInfo) <> 0 Then   Do   If Left(LCase(ProcessInfo.szExeFile), InStr(ProcessInfo.szExeFile, ".") + 3) = "notepad.exe" Then   '遍历进程,查找notepad.exe,找到后执行操作.......   End If   Loop While Process32Next(MySnapHandle, ProcessInfo) <> 0   End If   CloseHandle MySnapHandle   end sub   C++例子:   #include "StdAfx.h"   #include "windows.h"   #include "tlhelp32.h"   #include "stdio.h"   int main(int argc, char* argv[])   {   PROCESSENTRY32 pe32;   //在使用这个结构前,先设置它的大小   pe32.dwSize = sizeof(pe32);   //给系统内所有的进程拍个快照   HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);   if (hProcessSnap == INVALID_HANDLE_VALUE)   {   printf("CreateToolhelp32Snapshot 调用失败./n");   return -1;   }   //遍历进程快照,轮流显示每个进程的信息   BOOL bMore = ::Process32First(hProcessSnap,&pe32);   while (bMore)   {   printf("进程名称:%s/n",pe32.szExeFile);   printf("进程ID:%u/n/n",pe32.th32ProcessID);   bMore = ::Process32Next(hProcessSnap,&pe32);   }   //不要忘记清除掉snapshot对象   ::CloseHandle(hProcessSnap);   return 0;   }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

为什么必须要使用CloseHandle关闭句柄

 

1,线程和线程句柄(Handle)不是一个东西,线程是在cpu上运行的.....(说不清楚了),线程句柄是一个内核对象。我们可以通过句柄来操作线程,但是线程的生命周期和线程句柄的生命周期不一样的。线程的生命周期就是线程函数从开始执行到return,线程句柄的生命周期是从CreateThread返回到你CloseHandle()。

2,线程是一种内核对象,系统维护着每一个内核对象,当每个内核对象引用记数为0时,系统就从内存中释放该对象,CloseHandle就是将该线程对象的引用记数减1。所有的内核对象(包括线程Handle)都是系统资源,用了要还的,也就是说用完后一定要closehandle关闭之,如果不这么做,你系统的句柄资源很快就用光了。

3,如果你CreateThread以后需要对这个线程做一些操作,比如改变优先级,被其他线程等待,强制TermateThread等,就要保存这个句柄,使用完了在CloseHandle。如果你开了一个线程,而不需要对它进行如何干预,CreateThread后直接CloseHandle就行了。

所以

CloseHandel(ThreadHandle );

只是关闭了一个线程句柄对象,表示我不再使用该句柄,即不对这个句柄对应的线程做任何干预了。并没有结束线程。

如果你觉得多了一个变量,也可以写为:

CloseHandel(CreateThread(NULL,0,.....));

阅读更多
个人分类: 函数
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭