装载自http://hi.baidu.com/csw8923/blog/item/20f8f858320f5fd49c8204ac.html
1、进程控制
CreateToolhelp32Snapshot 函数给当前系统内执行的进程拍快照(Snapshot),列表中记录
着进程的ID、进程对应的可执行文件的名称和创建该进程的进程ID数据。
实用Process32First函数和Process32Next函数遍历快照中记录的列表。
#include "stdafx.h"
#include <windows.h>
#include <tlhelp32.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;
}
CreateToolhelp32Snapshot 用于获取系统内指定进程的快照,也可以被这些进程使用的堆、模块、线程快照。
函数具体用法:
HANDLE WINAPI CreateToolhelp32Snapshot(
DWORD dwFlags, // 用来指定"快照"中需要返回的对象,可以是TH32CS_SNAPPROCESS等
DWORD th32ProcessID // 一个进程ID号,用来指定要获取哪一个进程的快照,
// 当获取系统进程列表或当前进程快照时可以设为0
);
dwFlags参数指定了获取的列表的类型,其值可以是:
1.TH32CS_SNAPHEAPLIST 枚举th32ProcessID 参数指定的进程中的堆;
2.TH32CS_SNAPMODULE 枚举th32ProcessID 参数指定的进程中的模块;
3.TH32CS_SNAPPROCESS 枚举系统范围内的进程,进程th32ProcessID 参数被忽略;
4.TH32CS_SNAPTHREAD 枚举系统范围内的线程,此时thProcessID 参数被忽略;
成功返回一个快照句柄,否则返回INVALID_HANDLE_VALUE(即-1)
在快照列表中获取进程信息需要使用Process32First和Process32Next函数的每次调用仅返回一个进程的信息。
Process32First函数用来进行首次调用,以后的调用由Process32Next循环完成,直到所有的信息都被获取为止。
当不再有剩余信息的时候,函数返回FALSE,程序中使用下面的循环接过来获取进程列表。
BOOL bMore = ::Process32First(hProcessSnap, &pe32);
while(bMore)
{
printf(" 进程名称:%s \n", pe32.szExeFile);
printf(" 进程ID号:%u \n\n", pe32.th32ProcessID);
bMore = ::Process32Next(hProcessSnap, &pe32);
}
Process32First 和 Process32Next 函数的第一个参数是快照句柄,第二个参数是一个指向
PROCESSENTRY32结构的指针,进程信息将会被返回到这个结构中。 结构定义如下:
typeder struct
{ 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;
使用TillHelp函数并不是获取系统内的进程信息的惟一方法,函数EnumProcesses也可以完成这项任务,但Windows操作 系统不支持它。
2、终止当前进程
终止进程也就是结束程序的执行,让它从内存中卸载。进程终止的原因可能有4种:
(1)主线程的入口函数返回。
(2)进程中一个线程调用了ExitProcess函数。
(3)此进程中的所有线程都结束了。
(4)其他进程中的一个线程调用了TerminateProcess函数。
调用系统函数ExitProcess促使操作系统终止应用程序。
它会结束当前应用程序的执行,并设置它的退出代码。
其用法如下:
void ExitProcess(UINT uExitCode); // 参数 uExitCode为此程序的退出代码。
3、终止其他进程
ExitProcess函数只能用来结束当前进程,当然我们可以使用TerminateProcess函数来结束其他进程。
BOOL TerminateProcess(
HANDLE hProcess, // 要结束的进程(目标进程)的句柄
UINT uExitCode // 指定目标进程的退出代码,你可以使用GetExitCodeProcess取得一个进程的退出代码
);
而对于一个已经存在的进程,只能使用OpenProcess函数来取得进程的访问权限。函数用法如下:
HANDLE OpenProcess(
DWORD dwDesiredAccess, // 想得到的访问权限,可以是PROCESS_ALL_ACCESS等
BOOL bInheritHandle, // 指定返回的句柄是否可以被继承
DWORD dwProcessId // 指定要打开的进程的ID号
);
这个函数打开一个存在的进程并返回其句柄。dwDesiredAccess参数指定了对该进程的访问权限,这些权限可以是
PROCESS_ALL_ACCESS 所有可进行的权限
PROCESS_QUERY_INFORMATION 查看该进程信息的权限(还有许多没有列出)
其中bInheritHandle参数指定此函数返回的句柄是否可以被继承。dwProcessId参数指定了要打开进程的ID号,
也可以用ToolHelp函数获取。
BOOL TerminateProcessFromId(DWORD dwId)
{
BOOL bRet = FALSE;
// 打开目标进程,取得进程句柄
HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwId);
if(hProcess != NULL)
{
// 终止进程
bRet = ::TerminateProcess(hProcess, 0);
}
CloseHandle(hProcess);
return bRet;
}
其中TerminateProcessFromId函数传递一个进程ID号,试图去结束这个进程。
进一步调用GetLastError函数取得错误代码。GetLastError取得调用线程的最后出错代码。
调用GetExitCodeProcess函数可以取得其退出代码,调用这个函数,目标进程还没结束,函数还会返回STILL_ACTIVE,
表示进程还在运行。
一旦进程终止,会发生下面事件发生
(1)所有被这个进程创建或打开对象句柄就会关闭。
(2)此进程的所有线程将终止执行。
(3)进程内核对象变成守信状态,所有等待在此对象上的线程开始运行,即WaitForSingleObject函数返回。
(4)系统将进程对象中退出代码的值由STILL_ACTIVE改为指定的退出码。
浙公网安备 33010602011771号