CreateToolhelp32Snapshot 进程快照


#include <windows.h>

#include <tlhelp32.h>

#include <iostream>

 

int main(int argc, char* argv[])

{

       // 现在我们将利用函数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;
       // 必须设置PROCESSENTRY32的dwSize成员的值 ;  

       processInfo->dwSize = sizeof(PROCESSENTRY32);
       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("%-d%-s%-d/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;
       return 0;

}

 

 

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

zsl4619755436我的:收件箱资源博客空间设置|帮助|退出

  • 首页
  • 业界
  • 移动
  • 云计算
  • 研发
  • 论坛
  • 博客
  • 下载
  • 更多

公告:CSDN 搜索第二版正式上线!    CSDN论坛2012年度职场优秀帖评选活动正式开始!
2012CSDN博客之星评选正式上线      2000元大奖征异构开发博文      Q14年互联网产品进化史

枚举系统进程

分类: VC 2011-01-10 23:12 890人阅读 评论(0) 收藏 举报

枚举进程

要用到下面几个函数

1. HANDLE handle = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

得到系统的进程快照,参数0表示从当前进程取得。

 

2.    PROCESSENTRY32 procinfo;

procinfo.dwSize = sizeof(PROCESSENTRY32);

Process32First(handle, &procinfo)

得到第一个进程的信息,放在procinfo中,procinfo.th32ProcessID为进程ID, procinfo.szExeFile为进程名等。

 

3. Process32Next(handle, &procinfo)

继续枚举其它进程

 

下面是一段代码:

// 枚举进程

void CMyupdateDlg::OnProcesses()

{

 HANDLE handle = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

 if(handle==(HANDLE)-1) {

  AfxMessageBox("CreateToolhelp32Snapshot error");

  return;

 }

 PROCESSENTRY32 procinfo;

 procinfo.dwSize = sizeof(PROCESSENTRY32);

 

 if(::Process32First(handle, &procinfo))

 {

  do

  {

   CString str = procinfo.szExeFile;

   if(MessageBox(str, "", MB_OKCANCEL) == IDCANCEL)

   {

    ::CloseHandle(handle);

    return;

   }

 

  }

  while(::Process32Next(handle, &procinfo));

 

  ::CloseHandle(handle);

 }

 

}

 

如何杀死一个进程

HANDLE h = ::OpenProcess(PROCESS_ALL_ACCESS, false,  procinfo.th32ProcessID);

if(!h) AfxMessageBox("get handle failed.");

TerminateProcess(h, 0);

 

先用OpenProcess根据进程号得到一个进程的句柄,然后用TerminateProcess杀死进程

 

 枚举窗口

EnumWindows可以用来枚举顶层窗口。每一个参数为一个回调函数。下面是一个例子:

 

//枚举窗口

void CMyupdateDlg::OnWindow()

{

 EnumWindows(EnumWindowsProc, 0);

}

 

//枚举窗口函数

BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)

{

 TCHAR str[100];

 //if(::GetWindowLong(hWnd,GWL_STYLE)& WS_VISIBLE)  //&WS_POPUP//QQ

 ::GetWindowText(hWnd, str, 100);

 //::GetClassName(hWnd, str, 100);

 CString str2;

 str2.Format("%s", str);

 

 if(str2.Find("app")>=0)

 {

  AfxMessageBox(str2);

  //::SendMessage(hWnd, WM_CLOSE, 0 , 0);

  DWORD dwProcessID;

  ::GetWindowThreadProcessId(hWnd, &dwProcessID);

  HANDLE h = ::OpenProcess(PROCESS_ALL_ACCESS, false, dwProcessID);

  ::TerminateProcess(h, 0);

 }

 return TRUE;

}

 

其中,GetWindowLong用来取得指定窗口的一些信息,如是否可见等

GetWindowThreadProcessId从一个窗口句柄,得到当前窗口句柄所在进程的ID

 

总结:

1. 通过枚举进程可以得到进程的ID,再通过这个ID,可以对进程操作,如关闭等。

2. 通过EnumWindows枚举窗口句柄,得到的并不是进程的句柄,而是顶层窗口的。要关闭这个窗口,可以发送WM_CLOSE消息,但不能通过

TerminateProcess,直接利用这个句柄关闭。但可以通过GetWindowThreadProcessId得到窗口所在进程的句柄,再利用TerminateProcess关闭之。

3。这里面有进程、线程、纤程的根据在里面。还没有理清楚

http://blog.csdn.net/andylin02/archive/2008/01/27/2068476.aspx

 

 

 

CreateToolhelp32Snapshot枚举进程

每一个应用程序实例在运行起来后都会在当前系统下产生一个进程,大多数应用程序均拥有可视界面,用户可以通过标题栏上的关闭按钮关闭程序。但是也有为数不少的在后台运行的程序是没有可视界面的,对于这类应用程序用户只能通过CTRL+ALT+DEL热键呼出"关闭程序"对话框显示出当前系统进程列表,从中可以结束指定的任务。显然,该功能在一些系统监控类软件中还是非常必需的,其处理过程大致可以分为两步:借助系统快照实现对系统当前进程的枚举和根据枚举结果对进程进行管理。本文下面即将对此过程的实现进行介绍。

当前进程的枚举

要对当前系统所有已开启的进程进行枚举,就必须首先获得那些加载到内存的进程当前相关状态信息。在Windows操作系统下,这些进程的当前状态信息不能直接从进程本身获取,系统已为所有保存在系统内存中的进程、线程以及模块等的当前状态的信息制作了一个只读副本--系统快照,用户可以通过对系统快照的访问完成对进程当前状态的检测。在具体实现时,系统快照句柄的获取是通过Win32 API函数CreateToolhelp32Snapshot()来完成的,通过该函数不仅可以获取进程快照,而且对于堆、模块和线程的系统快照同样可以获取。

使用这个函数前必须在头文件里包含tlhelp32.h头文件。

CreateToolhelp32Snapshot函数为指定的进程、进程使用的堆[HEAP]、模块[MODULE]、线程[THREAD])建立一个快照[snapshot]。

HANDLE WINAPI CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID);

参数:其中,参数dwFlags:指定将要创建包含哪一类系统信息的快照句柄,本程序中只需要检索系统进程信息,因此可将其设置为TH32CS_SNAPPROCESS;函数第二个参数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。

备注:

使用GetLastError函数查找该函数产生的错误状态码。

要删除快照,使用CloseHandle函数。

在得到快照句柄之后只能以只读的方式对其进行访问。至于对系统快照句柄的使用同普通对象句柄的使用并没有什么太大区别,在使用完之后也需要通过CloseHandle()函数将其销毁。

 

BOOL Process32First()函数

参数:HANDLE hSnapshot 传入的Snapshot句柄

参数:LPPROCESSENTRY32 lppe 指向PROCESSENTRY32结构的指针

作用:从Snapshot得到第一个进程记录信息

 

BOOL Process32Next()函数

参数:HANDLE hSnapshot 传入的Snapshot句柄

参数:LPPROCESSENTRY32 lppe 指向PROCESSENTRY32结构的指针

作用:从Snapshot得到下一个进程记录信息

 

BOOL Module32First()函数

 

参数:HANDLE hSnapshot传入的Snapshot句柄

参数:LPMODULEENTRY3 lpme 指向一个 MODULEENTRY32结构的指针

作用:从Snapshot得到第一个Module记录信息

 

BOOL Module32Next()函数

参数:HANDLE hSnapshot传入的Snapshot句柄

参数:LPMODULEENTRY3 lpme 指向一个 MODULEENTRY32结构的指针

作用:从Snapshot得到下一个Module记录信息

 

BOOL Thread32First()函数

参数:HANDLE hSnapshot传入的Snapshot句柄

参数:LPTHREADENTRY32 lpte指向一个 THREADENTRY32结构的指针

作用:从Snapshot得到第一个Thread记录信息

 

BOOL Thread32Next()函数

参数:HANDLE hSnapshot传入的Snapshot句柄

参数:LPTHREADENTRY32 lpte指向一个 THREADENTRY32结构的指针

作用:从Snapshot得到下一个Thread记录信息

 

HANDLE OpenProcess()函数

 参数:DWORD dwDesiredAccess 权限描叙信息

这里我用到了PROCESS_ALL_ACCESS功能是具有所有权限

参数:BOOL bInheritHandle 确定该句柄是否可以被程继承

参数:dwPrcessID 进程ID号

作用:打开一个存在的进程对象

 

列举进程

在得到系统的快照句柄后,就可以对当前进程的标识号进行枚举了,通过这些枚举出的进程标识号可以很方便的对进程进行管理。进程标识号通过函数Process32First() 和 Process32Next()而得到,这两个函数可以枚举出系统当前所有开启的进程,并且可以得到相关的进程信息。 这两个函数原型声明如下:

      BOOL WINAPI Process32First(HANDLE hSnapshot, LPPROCESSENTRY32 lppe);

      BOOL WINAPI Process32Next(HANDLE hSnapshot,LPPROCESSENTRY32 lppe);

   以上两个函数分别用于获得系统快照中第一个和下一个进程的信息,并将获取得到的信息保存在指针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库的支持。通过这三个函数可以枚举出当前系统已开启的所有进程,并可获取到进程的各相关信息。

       

例子:

// EmuProcess.cpp : Defines the entry point for the console application.

//

 

#include "stdafx.h"

 

#include <windows.h>

#include <tlhelp32.h>

#include <iostream>

 

int main(int argc, char* argv[])

{

       // 现在我们将利用函数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;

      

       // 必须设置PROCESSENTRY32的dwSize成员的值 ;  

       processInfo->dwSize = sizeof(PROCESSENTRY32);

       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;

       return 0;

}

 

 

http://blog.csdn.net/andylin02/archive/2008/01/27/2068474.aspx

 

 

 

 

分享到:
  • 上一篇:GDI+ 中 delete 陷阱
  • 下一篇:HOOK文章
  • 查看评论

      暂无评论

    发表评论
    • 用 户 名:
    • zsl461975543
    • 评论内容:
    • 插入代码
      HTML/XML JavaScript CSS PHP C# C++ Java Python Ruby Visual Basic Delphi SQL 其它
        
    * 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    TOP
      个人资料

      cay22
      • 访问:179584次
      • 积分:3922分
      • 排名:第1070名
      • 原创:183篇
      • 转载:184篇
      • 译文:0篇
      • 评论:104条
      文章分类
    • ATL/WTL(13)
    • Boost(3)
    • C++模板(1)
    • C/C++(53)
    • DirectShow(2)
    • DirectX(2)
    • DLL(3)
    • E文(2)
    • GDI+(2)
    • HTML(2)
    • JAVA(9)
    • MySQL(8)
    • NetWork(2)
    • Office编程. Excel(1)
    • OpenCV(5)
    • Python(1)
    • QQ相关技术(1)
    • QT(7)
    • STL(6)
    • UI(6)
    • UML(1)
    • VC(121)
    • VC 控件(11)
    • WinCE(1)
    • wxWidgets(1)
    • XML(4)
    • 别人的Blog(4)
    • 图像(26)
    • 多媒体编程(3)
    • 大学生活(2)
    • 常用网址(2)
    • 数学(!!)(5)
    • 杂(11)
    • 汇编(29)
    • 版本控制(2)
    • 生活(3)
    • 生活小常识(2)
    • 电脑使用技巧(12)
    • 编程开发网站(2)
    • 编程思想及其相关实现(2)
    • 职业规划(2)
    • 设计模式(10)
    • 项目管理/项目实施/项目规范(1)
    • Window内核(1)
    • PE文件结构学习(16)
    • 批处理(4)
    • Android(1)
    • Win32汇编(11)
    • 反汇编(5)
    • 直线电机(1)
    • JSP(2)
      文章存档
    • 2012年12月(12)
    • 2012年11月(2)
    • 2012年10月(5)
    • 2012年08月(1)
    • 2012年06月(6)
    • 2012年04月(7)
    • 2012年03月(16)
    • 2012年02月(8)
    • 2012年01月(16)
    • 2011年12月(1)
    • 2011年11月(1)
    • 2011年09月(4)
    • 2011年08月(2)
    • 2011年07月(6)
    • 2011年06月(3)
    • 2011年05月(3)
    • 2011年04月(7)
    • 2011年03月(7)
    • 2011年02月(11)
    • 2011年01月(8)
    • 2010年12月(10)
    • 2010年11月(21)
    • 2010年10月(12)
    • 2010年09月(5)
    • 2010年08月(11)
    • 2010年07月(11)
    • 2010年06月(15)
    • 2010年05月(25)
    • 2010年04月(18)
    • 2010年03月(19)
    • 2010年02月(3)
    • 2010年01月(13)
    • 2009年12月(9)
    • 2009年11月(15)
    • 2009年10月(23)
    • 2009年09月(20)
    • 2009年08月(2)
    • 2009年07月(3)
    • 2008年11月(6)
      展开
      阅读排行
    • 图像处理中各种边缘检测的微分算子简单比较(Sobel,Robert, Prewitt,Laplacian,Canny)(7151)
    • 高斯分布函数解析(5814)
    • Canny边缘检测基本原理与C++实现(4821)
    • 高斯滤波实践(3253)
    • 基于区域的图像分割-----------区域生长(3252)
    • error C2220: 警告被视为错误 - 没有生成“object”文件(3057)
    • 形态学运算中腐蚀,膨胀,开运算和闭运算。(2963)
    • Bresenham画圆算法 与中点画圆法(2859)
    • 生成高斯模板(C++)(2814)
    • 关于这样的错误 libcpmtd.lib(string.obj) : error LNK2005: "public: void __thiscall (2700)
      评论排行
    • Canny边缘检测基本原理与C++实现(12)
    • 图像处理中各种边缘检测的微分算子简单比较(Sobel,Robert, Prewitt,Laplacian,Canny)(8)
    • 高斯滤波实践(6)
    • error C2220: 警告被视为错误 - 没有生成“object”文件(5)
    • 形态学运算中腐蚀,膨胀,开运算和闭运算。(5)
    • Sobel边缘检测算法(5)
    • CDialogBar的具体使用过程一(3)
    • 关于这样的错误 libcpmtd.lib(string.obj) : error LNK2005: "public: void __thiscall (3)
    • 各种图像分割方法(3)
    • OpenCV 矩阵操作 CvMat(二)(3)
      推荐文章
      最新评论
    • Sobel边缘检测算法

      自溟: 学习了。乘4是为何?通常乘3的。

    • Sobel边缘检测算法

      yizhanhaha: 好吧,大神!

    • 形态学运算中腐蚀,膨胀,开运算和闭运算。

      wangjian8855: 你的例子 是不是反了。 //如果源图像中当前点自身或者左右有一个点不是黑色, ...

    • CListCtrl 常用的一些代码

      淮河神: NM_LISTVIEW

    • 均值滤波器 ( Mean Filter ) C++ 实现

      tianzhaixing: 楼主好专业,学习了...

    • 线程池原理及创建(C++实现)

      wziyx513225244: 真心不错的文章,学习了。谢谢楼主的分享。

    • 教大家建立一个别人既无法进入又无法删除的文件夹

      小蓝鸟贵薪: 有DELPHI编程并且不调用DOS的命令的方法吗

    • 获得CPU序列号, 获得硬盘序列号, 监听硬盘大小的源码工程

      Liulangzhe2008: just take a look

    • 罗云彬win32汇编教程笔记 变量的使用

      s0sky: 讲的好极了!果断要顶!!!

    • 图像处理中各种边缘检测的微分算子简单比较(Sobel,Robert, Prewitt,Laplacian,Canny)

      linyuanxs: 学习了

    公司简介| 招贤纳士| 广告服务| 银行汇款帐号| 联系方式| 版权声明| 法律顾问| 问题报告
    京 ICP 证 070598 号
    北京创新乐知信息技术有限公司 版权所有
    世纪乐知(北京)网络技术有限公司 提供技术支持
    江苏乐知网络技术有限公司 提供商务支持
    联系邮箱:webmaster(at)csdn.net
    Copyright © 1999-2012, CSDN.NET, All Rights Reserved  GongshangLogo

     

    你可能感兴趣的:(CreateToolhelp32Snapshot 进程快照)