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;

}

 

 

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

分类: 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

 

 

 

 

分享到:
查看评论

  暂无评论

发表评论
  • 用 户 名:
  • zsl461975543
  •   
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
TOP
  • 个人资料
    • 访问:179584次
    • 积分:3922分
    • 排名:第1070名
    • 原创:183篇
    • 转载:184篇
    • 译文:0篇
    • 评论:104条
  • 推荐文章
  • 最新评论
公司简介| 招贤纳士| 广告服务| 银行汇款帐号| 联系方式| 版权声明| 法律顾问| 问题报告
京 ICP 证 070598 号
北京创新乐知信息技术有限公司 版权所有
世纪乐知(北京)网络技术有限公司 提供技术支持
江苏乐知网络技术有限公司 提供商务支持
联系邮箱:webmaster(at)csdn.net
Copyright © 1999-2012, CSDN.NET, All Rights Reserved  GongshangLogo

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值