2024年3月25日发(作者:)

WIN32进程快照以及进程ID和句柄查找 收藏

要对进程进行某种操作,就必须首先知道该进程的进程句柄或者进程ID,否则一切

无从谈起,对于程序自己创建的子进程来说,CreateProcess函数返回了进程句柄和进程

ID,但如果需要调试系统中已经运行的进程,那就必须首先获取它们的句柄才行。Win32

中并没有直接获取其他进程句柄的函数,但如果知道进程ID,可以由此得到进程句柄,所

以可以首先通过某种途径获取进程ID。

一、获取进程ID

1. 从窗口句柄获取进程句柄

获取进程ID的方法之一是使用GetWindowThreadProcessId函数,这个函数可以

从一个窗口句柄获得创建该窗口的进程的进程ID,而通过FindWindow函数得到窗口句

柄是很简单的,所以GetWindowThreadProcessId函数的用途相当广泛。该函数的用法

是:

DWORD GetWindowThreadProcessId(

HWND hWnd, // handle to window

LPDWORD lpdwProcessId // process identifier

);

其中hWnd参数指定需要用来获取进程ID的窗口句柄,lpdwProcessId指向一个

双字变量,函数在这里返回创建窗口的进程ID,函数的返回值是目标进程中创建该窗口的

线程的线程句柄(一个有用的副产品!)。

2. 通过快照来获取进程ID

每一个应用程序实例在运行起来后都会在当前系统下产生一个进程,大多数应用程

序均拥有可视界面,用户可以通过标题栏上的关闭按钮关闭程序。但是也有为数不少的在

后台运行的程序是没有可视界面的,对于这类应用程序用户只能通过CTRL+ALT+DEL热

键呼出"关闭程序"对话框显示出当前系统进程列表,从中可以结束指定的任务。显然,该

功能在一些系统监控类软件中还是非常必需的,其处理过程大致可以分为两步:借助系统

快照实现对系统当前进程的枚举和根据枚举结果对进程进行管理。本文下面即将对此过程

的实现进行介绍。

当前进程的枚举

要对当前系统所有已开启的进程进行枚举,就必须首先获得那些加载到内存的进程当

前相关状态信息。在Windows操作系统下,这些进程的当前状态信息不能直接从进程本

身获取,系统已为所有保存在系统内存中的进程、线程以及模块等的当前状态的信息制作

了一个只读副本--系统快照,用户可以通过对系统快照的访问完成对进程当前状态的检测。

在具体实现时,系统快照句柄的获取是通过Win32 API函数CreateToolhelp32Snapshot()

来完成的,通过该函数不仅可以获取进程快照,而且对于堆、模块和线程的系统快照同样

可以获取。该函数原型声明如下:

HANDLE WINAPI CreateToolhelp32Snapshot(DWORD dwFlags,DWORD

th32ProcessID);