1. 概述
这篇博客将主要讲进程的管理,主要涉及到打开进程(OpenProcess()函数)、终止进程(TerminateProcess()函数)、对当前进程进行权限修改(OpenProcessToken(), AdjustTokenPrivileges()函数)、窗口查找(FindWindow()函数)。接下来就将使用这些函数实现对进程的打开和关闭操作。
2. 进程操作
2.1 打开进程
这里使用到的函数是OpenProcess()函数,它的函数原型为
HANDLE WINAPI OpenProcess(
_In_ DWORD dwDesiredAccess, //打开的权限
_In_ BOOL bInheritHandle, //是否继承句柄
_In_ DWORD dwProcessId //进程PID
);
编码例子
//************************************************************************
// 函数名称: my_openprocess
// 访问权限: public
// 创建日期: 2017/06/04
// 创 建 人:
// 函数说明: 打开指定进程PID的进程返回进程句柄
// 函数参数: DWORD proPID 需要操作的进程的PID
// 返 回 值: HANDLE
//************************************************************************
HANDLE my_openprocess(DWORD proPID)
{
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, false, proPID);
if (INVALID_HANDLE_VALUE == hProc)
{
cout << "open process failed" << endl;
return NULL;
}
return hProc;
}
2.2 提升当前进程权限
当在对其他进程进行操作的时候,会遇到操作权限不足的情况,这时就需要对进程权限进行提升,代码如下:
//************************************************************************
// 函数名称: my_adjustPrivileges
// 访问权限: public
// 创建日期: 2017/06/04
// 创 建 人:
// 函数说明: 提升当前进程权限
// 返 回 值: bool
//************************************************************************
bool my_adjustPrivileges()
{
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken)) //获得进程访问令牌
{
if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid))
{
//提升进程的权限
AdjustTokenPrivileges(hToken, false, &tkp, 0x10, (PTOKEN_PRIVILEGES)NULL, 0);
}
if (hToken)
CloseHandle(hToken);
}
else
return false;
}
2.3 终止进程
终止进程使用的是TerminateProcess()函数,原型为:
BOOL WINAPI TerminateProcess(
_In_ HANDLE hProcess, //进程的句柄
_In_ UINT uExitCode //进程退出的退出代码:0-正常退出;非0-退出异常
);
之前在一篇博客里面讲到了TerminateProcess和ExitProcess的区别。
2.4 查找进程
查找进程这里使用到的函数是FindWindow,它的函数原型为
HWND WINAPI FindWindow(
_In_opt_ LPCTSTR lpClassName, //查找的窗口的类名
_In_opt_ LPCTSTR lpWindowName //查找的窗口的窗口标题
);
窗口的类名和窗口的标题可以通过VS中的工具Spy++来实现,使用方法如下图所示:
首先,进入Spy++,之后点击查找窗口
将光标移动到需要查找窗口上,就可以得到需要的相关参数信息
FindWindow()函数返回的是窗口的句柄,得到窗口的句柄之后就需要通过窗口句柄来得到进程的PID。因而大体的流程就是这样的:
(1)通过查找窗口函数FindWindow找到进程窗口句柄
(2)通过窗口句柄得到进程的PID
(3)由进程的PID得到进程的句柄
代码示例:
//************************************************************************
// 函数名称: my_openprocess_byWindName
// 访问权限: public
// 创建日期: 2017/06/04
// 创 建 人:
// 函数说明: 通过进程的窗口名来得到进程的句柄
// 返 回 值: HANDLE
//************************************************************************
HANDLE my_openprocess_byWindName()
{
HWND hwnd = ::FindWindow( _T("CalcFrame"), _T("计算器")); //获得进程的窗口句柄
DWORD m_proPID;
::GetWindowThreadProcessId(hwnd, &m_proPID); //由窗口句柄得到进程的PID
HANDLE m_hPro = my_openprocess(m_proPID);
return m_hPro;
}