李sir_Blog

博客园 首页 联系 订阅 管理

装载自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改为指定的退出码。

posted on 2010-06-03 11:21  李sir  阅读(250)  评论(0)    收藏  举报