【Windows核心编程】Windows核心编程 -- 进程(示例:枚举进程)

枚举进程 

     每一个应用程序实例在运行起来后都会在当前系统下产生一个进程,大多数应用程序均拥有可视界面,用户可以通过标题栏上的关闭按钮关闭程序。但是也有为数不少的在后台运行的程序是没有可视界面的,对于这类应用程序用户只能通过CTRL+ALT+DEL热键呼出"关闭程序"对话框显示出当前系统进程列表,从中可以结束指定的任务。显然,该功能在一些系统监控类软件中还是非常必需的,

      其处理过程大致可以分为两步:借助系统快照实现对系统当前进程的枚举和根据枚举结果对进程进行管理。
      在Windows操作系统下,这些进程的当前状态信息不能直接从进程本身获取,系统已为所有保存在系统内存中的进程、线程以及模块等的当前状态的信息制作了一个只读副本--系统快照,用户可以通过对系统快照的访问完成对进程当前状态的检测。在具体实现时,系统快照句柄的获取是通过Win32 API函数CreateToolhelp32Snapshot()来完成的,通过该函数不仅可以获取进程快照,而且对于堆、模块和线程的系统快照同样可以获取。
       使用这个函数前必须在头文件里包含tlhelp32.h头文件。
       函数为指定的进程、进程使用的堆[HEAP]、模块[MODULE]、线程[THREAD])建立一个快照[snapshot]。
        HANDLE WINAPI CreateToolhelp32Snapshot(
            DWORD dwFlags,  //指定将要创建包含哪一类系统信息的快照句柄,本程序中只需要检索系统进程信息,因此可将其设置为TH32CS_SNAPPROCESS;
            DWORD th32ProcessID //则指定了进程的标识号,当设置为0时指定当前进程
        );

[dwFlags]指定快照中包含的系统内容,这个参数能够使用下列数值(变量)中的一个。

TH32CS_INHERIT - 声明快照句柄是可继承的。

TH32CS_SNAPALL - 在快照中包含系统中所有的进程和线程。

TH32CS_SNAPHEAPLIST - 在快照中包含在th32ProcessID中指定的进程的所有的堆。

TH32CS_SNAPMODULE -  在快照中包含在th32ProcessID中指定的进程的所有的模块

TH32CS_SNAPPROCESS - 在快照中包含系统中所有的进程

TH32CS_SNAPTHREAD - 在快照中包含系统中所有的线程。

[th32ProcessID ]指定将要快照的进程ID。如果该参数为0表示快照当前进程。该参数只有在设置了TH32CS_SNAPHEAPLIST或TH32CS_SNAPMOUDLE后才有效,在其他情况下该参数被忽略,所有的进程都会被快照。
返回值:调用成功,返回快照的句柄,调用失败,返回INVAID_HANDLE_VALUE。


要删除快照,使用CloseHandle函数。 在得到快照句柄之后只能以只读的方式对其进行访问。

BOOL WINAPI Process32First(        //作用:从Snapshot得到第一个进程记录信息
  HANDLE        hSnapshot,            //_in
  LPPROCESSENTRY32   lppe   //_out
  );

BOOL WINAPI Process32Next(   //从Snapshot得到下一个进程记录信息

   HANDLE hSnapshot,

   LPPROCESSENTRY32 lppe

  ); 

类似函数如下:
BOOL Module32First()函数
BOOL Module32Next()函数
BOOL Thread32First()函数  //从Snapshot得到第一个Thread记录信息
BOOL Thread32Next()函数  //从Snapshot得到下一个Thread记录信息
HANDLE OpenProcess()函数

HANDLE OpenProcess(

  DWORD  dwDesiredAccess, //渴望得到的访问权限(标志)
  BOOL  bInheritHandle,        // 是否继承句柄
  DWORD  dwProcessId        // 进程标示符
  ); 

列举进程
         在得到系统的快照句柄后,就可以对当前进程的标识号进行枚举了,通过这些枚举出的进程标识号可以很方便的对进程进行管理。进程标识号通过函数Process32First() 和 Process32Next()而得到。 用于获得系统快照中第一个和下一个进程的信息,并将获取得到的信息保存在指针lppe所指向的PROCESSENTRY32结构中。函数第一个参数hSnapshot为由CreateToolhelp32Snapshot()函数返回得到的系统快照句柄;第二个参数lppe为指向结构PROCESSENTRY32的指针,PROCESSENTRY32结构可对进程作一个较为全面的描述,其定义如下:
typedef struct tagPROCESSENTRY32 {

DWORD dwSize; // 结构大小;

DWORD cntUsage; // 此进程的引用计数;

DWORD th32ProcessID; // 进程ID;

DWORD th32DefaultHeapID; // 进程默认堆ID;

DWORD th32ModuleID; // 进程模块ID;

DWORD cntThreads; // 此进程开启的线程计数;

DWORD th32ParentProcessID; // 父进程ID;

LONG pcPriClassBase; // 线程优先权;

DWORD dwFlags; // 保留;

char szExeFile[MAX_PATH]; // 进程全名;

} PROCESSENTRY32;

     以上三个API函数均在头文件tlhelp32.h中声明,运行时需要有kernel32.lib库的支持。


示例:

#include <Windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
#include "tlhelp32.h"
int main( )
{
    /* 现在我们将利用函数CreateToolhelp32Snapshot()获得当前运行进程的快照
       这个函数返回包含正在运行进程的快照句柄。
       他的原形是:
              HANDLE WINAPI CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID);
       我们将dwFlags设为TH32CS_SNAPPROCESS,th32ProcessID置为0。
    */
	HANDLE hSnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);

	/*现在我们获得了所有进程的信息。
	  将从hSnapShot中抽取数据到一个PROCESSENTRY32结构中
	  这个结构代表了一个进程,是ToolHelp32 API的一部分。
	  抽取数据靠Process32First()和Process32Next()这两个函数。

	  这里我们仅用Process32Next(),他的原形是:
	  BOOL WINAPI Process32Next(HANDLE hSnapshot,LPPROCESSENTRY32 lppe);
	  我们程序的代码中加入:
	*/
	PROCESSENTRY32* processInfo=new PROCESSENTRY32;
	processInfo->dwSize=sizeof(PROCESSENTRY32);// 必须设置PROCESSENTRY32的dwSize成员的值 ;
	int index=0;

	//这里我们将快照句柄和PROCESSENTRY32结构传给Process32Next()。
	//执行之后,PROCESSENTRY32 结构将获得进程的信息。我们循环遍历,直到函数返回FALSE。

	printf("****************开始列举进程****************\n");
	while(Process32Next(hSnapShot,processInfo)!=FALSE)
	{
		index++;
		printf("****************** %d ******************\n",index);
		printf("PID             Name Current       Threads\n");
		printf("%-15d%-25s%-4d\n",processInfo->th32ProcessID,processInfo->szExeFile,processInfo->cntThreads);
	}

	CloseHandle(hSnapShot);
	printf("****************进程列举结束****************\n");


	int processID;
	HANDLE hProcess;

	printf("Enter Process ID to terminate that process:");
	scanf("%d",&processID);
	// 现在我们用函数 TerminateProcess()终止进程:
	// 这里我们用PROCESS_ALL_ACCESS
	hProcess=OpenProcess(PROCESS_ALL_ACCESS,TRUE,processID);
	if(hProcess==NULL)
	{
		printf("Unable to get handle of process: ");
		printf("Error is: %d",GetLastError());
	}
	TerminateProcess(hProcess,0);

	delete processInfo;

    system("pause");
    return TRUE;
}


 



你可能感兴趣的:(【Windows核心编程】Windows核心编程 -- 进程(示例:枚举进程))