C/C++程序设计专题互联网@时事传播梦想

进程控制

2019-07-11  本文已影响15人  307656af5a04

进程控制

1、获取系统进程

2、终止当前进程

3、终止其他进程

4、保护进程

5、进程内存空间说明

6、读进程内存空间

7、写进程内存空间


1、获取系统进程

CreateToolhelp32Snapshot用于获取系统内指定进程的快照

HANDLE WINAPI CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID);

dwFlags指定获取的列表类型

th32ProcessID进程ID,指定那个进程,当获取系统进程列表或当前进程时取0

函数执行成功,返回一个快照句柄,否则返回INVALID_HANDLE_VALUE

| TH32CS_SNAPHEAPLIST | 枚举th32ProcessID参数指定的进程中的堆 |
| TH32CS_SNAPMODULE | 枚举th32ProcessID参数指定的进程中的模块 |
| TH32CS_SNAPPROCESS | 枚举系统范围内的进程,此时th32ProcessID被忽略 |
| TH32CS_SNAPTHREAD | 枚举系统范围内的线程,此时th32ProcessID被忽略 |

从快照列表中获取进程信息使用Process32First和Process32Next函数,每次调用仅返回一个进程的信息。当不再有剩余信息时,函数返回FALSE.

BOOL WINAPI Process32First(HANDLE hSnapshot, LPPROCESSENTRY32 lppe);

BOOL WINAPI Process32Next(HANDLE hSnapshot, LPPROCESSENTRY32 lppe);

LPPROCESSENTRY32 结构体

typedef struct tagPROCESSENTRY32
{
    DWORD dwSize;            // 结构体的长度,预先设置
    DWORD cntUsage;            // 进程的引用计数
    DWORD th32ProcessID;        // 进程ID
    ULONG_PTR th32DefaultHeapID;    // 进程默认的堆
    DWORD th32ModuleID;        // 进程模块ID
    DWORD cntThreads;            // 进程创建的线程数
    DWORD th32ParentProcessID;    // 进程的父进程ID
    LONG  pcPriClassBase;        // 进程创建的线程的基本优先级
    DWORD dwFlags;                // 内部使用
    TCHAR szExeFile[MAX_PATH];    // 进程对应可执行文件名 
}PROCESSENTRY32,*PPROCESSENTRY32;

例子

#define _AFXDLL
#include <afx.h>
#include <TlHelp32.h>  // 声明快照函数的头文件

int main()
{
    // 使用这个结构体之前,先设置它的大小
    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",pe32.th32ProcessID);
        bMore = ::Process32Next(hProcessSnap,&pe32);
    }

    // 清除snapshot对象
    ::CloseHandle(hProcessSnap);

    system("pause");
    return 0;
}

** 2、终止当前进程**

终止当前进程就是进程如何终止自己的运行。方法有两个

-- 主线程的入口函数返回,返回时,启动函数调用exit,并将用户的返回值传给它。exit销毁所有全局的和静态的对象,然后调用ExitProcess促使OS终止应用程序。

-- 程序也可以显式调用ExitProcess,但这样做无法销毁全局的和静态的对象。

void ExitProcess(UINT uExitCode);

捕获进程(已结束)退出的代码

BOOL GetExitCodeProcess(HANDLE hProcess,LPDWORD lpExitCode);

hProcess[in] Handle to the process

lpExitCode[in] Pointer to 32-bit variable to receive the process termination status.

lpExitCode用于装载进程退出代码的一个长整数变量。如进程尚未终止,则取得常数STILL_ACTIVE。

退出代码也称为进程的返回值,该值存储于进程内核对象中。

3、终止其他进程

BOOL TerminateProcess(HANDLE hProcess , DWORD uExitCode);

hProcess : 指定被终止的进程句柄

uExitCode : 指定目标进程的退出代码,也可以使用GetExitCodeProcess取得一个进程的退出代码。

取得进程句柄的两种方法

-- CreateProcess 会返回进程句柄

-- 对于一个已存在的进程,首先得到其进程ID,然后使用OpenProcess取得这个进程的访问权限。

HANDLE OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId);

dwDesiredAccess:想得到的访问权限,PROCESS_ALL_ACCESS

bInheritHandle:指定返回句柄是否可被继承

dwProcessId:指定要打开的进程ID

返回进程的句柄

OpenProcess执行失败后返回NULL,这时可进一步调用GetLastError取得错误代码。

例子

#include <stdio.h>
#include <Windows.h>

// 通过进程ID终止进程
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;
}

// 测试程序
int main()
{
    DWORD dwId;

    printf("请输入进程号\n");
    scanf("%u",&dwId);

    // 通过进程ID终止进程
    if (TerminateProcessFromID(dwId))
    {
        printf("进程终止成功\n");
    }
    else
    {
        printf("进程终止失败\n");
    }

    system("pause");
    return 0;
}

4、进程内存空间说明

32位OS可寻址4GB的地址空间,也就是OS的虚拟内存空间位4G,win2000开始,64K--2G给应用程序预留,2G--4G为OS预留,0--64K不被映射,目的是为了捕捉程序种的错误。

每个进程占用的内存空间是离散的,所以要访问进程内存中的一个值,就需要遍历整个64K---2G的地址空间。

Windows采用分页机制管理内存,每页的大小为4K(X86处理器上),也就是说Windows以4K为单位为应用程序分配内存。

5、读进程内存空间

BOOL ReadProcessMemory(HANDLE hProcess , LPCVOID lpBaseAddress , LPVOID lpBuffer , DWORD nSize , LPDWORD lpNumberOfBytesRead);
hProcess:待读进程句柄
lpBaseAddress:目标进程待读内存起始地址
lpBuffer:用来接收读取数据的缓冲区
nSize:要读取的字节数
lpNumberOfBytesRead:实际读取的字节数

6、写进程内存空间

BOOL WriteProcessMemory(HANDLE hProcess , LPCVOID lpBaseAddress , LPVOID lpBuffer , DWORD nSize , LPDWORD lpNumberOfBytesWritten);
参数含义与ReadProcessMemory相同
typedef void* LPVOID
typedef CONST void* LPCVOID
typedef DWORD* LPDWORD
typedef unsigned long DWORD; 32-bit unsigned integer;

上一篇下一篇

猜你喜欢

热点阅读