Chinaunix首页 | 论坛 | 博客
  • 博客访问: 957597
  • 博文数量: 120
  • 博客积分: 6454
  • 博客等级: 准将
  • 技术积分: 1739
  • 用 户 组: 普通用户
  • 注册时间: 2007-06-28 17:45
文章分类

全部博文(120)

文章存档

2014年(1)

2013年(1)

2012年(11)

2011年(16)

2010年(6)

2009年(11)

2008年(30)

2007年(44)

分类: C/C++

2007-11-29 16:56:43

     在 Windows 下可以通过使用 PSAPI 库来创建进程列表,用以枚举正在运行的进程的信息。为了使用 PSAPI 库中的函数,需要在 Platform SDK 中找到 PSAPI.h 和 PSAPI.lib 两个文件, PSAPI.h 里声明了所需要的函数。

#include "PSAPI.h"
#pragma comment(lib, "psapi.lib")

     要创建进程列表首先要调用 EnumProcesses()函数。该函数的声明如下:

BOOL

WINAPI

EnumProcesses(

    DWORD *lpidProcess,

    DWORD cb,

    DWORD *cbNeeded

);

     其中,DWORD 类型的数组指针 lpidProcess;该数组的大小尺寸 cb;以及一个指向 DWORD 的指针 cbNeeded,它接收返回数据的长度。DWORD 数组用于保存当前运行的进程ID。cbNeeded 返回数组所用的内存大小。

     然后通过

int nProcesses = cbNeeded / sizeof(DWORD);

     可以得到进程的总数。

     值得注意的是:虽然文档将返回的 DWORD 命名为“cbNeeded”,实际上是没有办法知道到底要传多大的数组的。EnumProcesses()根本不会在 cbNeeded 中返回一个大于 cb 参数传递的数组值。结果,唯一确保 EnumProcesses()函数成功的方法是分配一个 DWORD 数组,并且,如果返回的 cbNeeded 等于 cb,分配一个较大的数组,并不停地尝试直到cbNeeded 小于 cb 。

     这样,就获得了一个数组,其元素保存着系统中每个进程的ID。

     如果你要想获取进程的名字,那么必须首先获取一个句柄。从进程 ID 得到句柄,就得调用 OpenProcess()函数:

WINBASEAPI

HANDLE

WINAPI

OpenProcess(

    DWORD dwDesiredAccess,

    BOOL bInheritHandle, 

    DWORD dwProcessId

);

     其中 dwProcessId 就是刚刚得到的进程 ID。

     得到了 HANDLE ,则需要得到该进程的第一个模块。为此调用 EnumProcessModules() API:

BOOL
WINAPI
EnumProcessModules(
    HANDLE hProcess,
    HMODULE *lphModule,
    DWORD cb,
    LPDWORD lpcbNeeded
);

     调用之后,hModule 变量中保存的将是进程中的第一个模块。记住进程其实没有名字,但进程的第一个模块既是该进程的可执行模块。

     现在你可以用 hModule 中返回的模块句柄调用 GetModuleBaseName() API 函数获取全路径名,或者是进程的可执行模块名:

DWORD GetModuleBaseName(
  HANDLE hProcess,
  HMODULE hModule,
  LPTSTR lpBaseName,
  DWORD nSize
);

     函数四个参数分别是:进程句柄,模块句柄,返回名字的缓冲指针以及缓冲大小尺寸。其中的lpBaseName就是模块名字了。

     下面是一个我写的通过进程名得到进程ID的小例子,只需稍加改动就能得到其他的功能了。

DWORD getProcessByName(LPCTSTR name)
{
//    LPCTSTR name = "foxmail.exe";

    DWORD aProcesses[1024], cbNeeded, ModNeeded;
    if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
        return -1;

    // Calculate how many process identifiers were returned.

    HANDLE hProcess;
    HMODULE hMod;
    char szProcessName[MAX_PATH] = "unknown";
    int nProcesses = cbNeeded / sizeof(DWORD);
    for ( int i = 0; i < nProcesses; i++ )
    {
        hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
                                PROCESS_VM_READ,
                                FALSE, aProcesses[i] );
        if (NULL != hProcess )
        {
            if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), &ModNeeded) )
            {
                GetModuleBaseName( hProcess, hMod, szProcessName,
                                 sizeof(szProcessName) );
                if (stricmp(szProcessName, name) == 0)
                {
                    return aProcesses[i];
                }
            }
            else
                continue;
        }
    }
    return -1;
}

阅读(2105) | 评论(0) | 转发(0) |
0

上一篇:设置环境变量三法

下一篇:《盲山》?

给主人留下些什么吧!~~