进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,每一个进程都是一个实体有属于自己的地址控件,进程也是一个执行的程序(也就是说一个运行中的程序就是一个进程(这是小编自己的理解))。那我们如何打开系统上的一些进程,上一篇讲了通过winExec、ShellExecute、ShellExecuteEx、CreateProcess函数创建进程。这一篇就讲如何打开和关闭进程、动态获取进程号、关闭自身进程。
打开进程
所要使用到的函数
1、OpenProcess 函数用来打开一个已存在的进程对象,并返回进程的句柄。
1)函数原型
HANDLE OpenProcess(
DWORD dwDesiredAccess, //渴望得到的访问权限(标志)
BOOL bInheritHandle, // 是否继承句柄
DWORD dwProcessId// 进程标示符
);
2)参数:
- dwDesiredAccess :获取的权限,可分为以下几种
PROCESS_ALL_ACCESS: | 获取所有权限 |
---|---|
PROCESS_CREATE_PROCESS | 创建进程 |
PROCESS_CREATE_THREAD: | 创建线程 |
PROCESS_DUP_HANDLE: | 使用DuplicateHandle()函数复制一个新句柄 |
PROCESS_QUERY_INFORMATION: | 获取进程的令牌、退出码和优先级等信息 |
PROCESS_QUERY_LIMITED_INFORMATION: | 获取进程特定的某个信息 |
PROCESS_SET_INFORMATION: | 设置进程的某种信息 |
PROCESS_SET_QUOTA: | 使用SetProcessWorkingSetSize函数设置内存限制 |
PROCESS_SUSPEND_RESUME: | 暂停或者恢复一个进程 |
PROCESS_TERMINATE: | 使用Terminate函数终止进程 |
PROCESS_VM_OPERATION: | 在进程的地址空间执行操作 |
PROCESS_VM_READ: | 使用ReadProcessMemory函数在进程中读取内存 |
PROCESS_VM_WRITE: | 使用WriteProcessMemory函数在进程中写入内存 |
SYNCHRONIZE: | 使用wait函数等待进程终止 |
- bInheritHandle:TRUE或者FALSE
- dwProcessId:进程号
3)返回值:
如成功,返回值为指定进程的句柄。
如失败,返回值为空,可调用GetLastError获得错误代码。
注意:一般使用PROCESS_ALL_ACCESS权限,有可能打开进程的时候会失败,这时候就需要我们提升我们软件的权限了。
4)例子:打开计算器的进程
1、定义一个全局的进程句柄和进程号
HANDLE hProc;
int m_luid;//进程号
2、打开计算器的进程
void C打开进程_终止进程Dlg::OnBnClickedOpenProcess()
{
// TODO: 在此添加控件通知处理程序代码
RaisePrivileges();//提升权限
hProc = OpenProcess(PROCESS_ALL_ACCESS,FALSE,13724);//打开进程
if (hProc == NULL)
{
AfxMessageBox(_T("Opem Process failed"));
}
else
{
AfxMessageBox(_T("Opem Process ok"));
}
}
2、提升软件权限
void C打开进程_终止进程Dlg::RaisePrivileges()
{
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))//查看当前进程的权限,将其写入tkp结构体中
{
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0x10, (PTOKEN_PRIVILEGES)NULL,0);//修改当前的进程权限
}
}
if (hToken) CloseHandle(hToken);//关机令牌
}
关闭进程
所要使用到的函数
1、TerminateProcess关闭一个进程函数,返回BOOL
1) 函数原型
BOOL TerminateProcess(
HANDLE hProcess,//进程句柄
UINT uExitCode //进程终止码
);
2) 参数
- hProcess 指定要中断的一个进程的句柄
- uExitCode进程的一个退出代码
3) 返回值
非零表示成功,零表示失败。会设置GetLastError
4) 例子:关闭计算器进程
void C打开进程_终止进程Dlg::OnBnClickedCloseProcess()
{
// TODO: 在此添加控件通知处理程序代码
TerminateProcess(hProc,0);
}
动态获取进程ID
在打开或者关闭进程的时候都需要用到进程的ID,如果通过资源管理自己添加进程ID的话那操作很繁琐而且进程ID也会变化,那么我们如何动态获取进程ID。那就需要以下方法,通过FindWindow函数来获区进程窗口句柄,之后通过GetWindowThreadProcessId函数l来获取进程ID。
所要使用到的函数
1、FindWindow 这个函数检索处理顶级窗口的类名和窗口名称匹配指定的字符串。这个函数不搜索子窗口。
1)函数原型
HWND FindWindow(LPCSTR lpClassName,LPCSTR lpWindowName);
2)参数:
- lpClassName指向一个以NULL字符结尾的、用来指定类名的字符串或一个可以确定类名字符串的原子。如果这个参数是一个原子,那么它必须是一个在调用此函数前已经通过GlobalAddAtom函数创建好的全局原子。这个原子(一个16bit的值),必须被放置在lpClassName的低位字节中,lpClassName的高位字节置零。如果该参数为null时,将会寻找任何与lpWindowName参数匹配的窗口。
- lpWindowName指向一个以NULL字符结尾的、用来指定窗口名(即窗口标题)的字符串。如果此参数为NULL,则匹配所有窗口名。
3)返回值
- 如果函数执行成功,则返回值是拥有指定窗口类名或窗口名的窗口的句柄。
- 如果函数执行失败,则返回值为 NULL 。可以通过调用GetLastError函数获得更加详细的错误信息。
2、GetWindowThreadProcessId是一种计算机函数,功能是找出某个窗口的创建者(线程或进程),返回创建者的标志符。
1)函数原型
DWORD GetWindowThreadProcessId(
HWND hWnd,
LPDWORD lpdwProcessId
);
2)参数
- hWnd[in] (向函数提供的)被查找窗口的句柄.
- lpdwProcessId[out] 进程号的存放地址(变量地址)(如果参数不为NULL,即提供了存放处–变量,那么本函数把进程标志拷贝到存放处,否则不动作。)
3)返回值
- 返回线程号,注意,lpdwProcessId 是存放进程号的变量。返回值是线程号,lpdwProcessId 是进程号存放处。
4)例子:打开记事本进程
void C打开进程_终止进程Dlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
DWORD pid;
HWND hNotepad = ::FindWindow(_T("Notepad"),_T("1 - 记事本")); //通过类和文件名查找窗口句柄
GetWindowThreadProcessId(hNotepad,&pid);
m_luid = pid;
RaisePrivileges();
hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (hProc == NULL)
{
AfxMessageBox(_T("Opem Process failed"));
}
else
{
AfxMessageBox(_T("Opem Process ok"));
}
}
关闭自身进程
void C打开进程_终止进程Dlg::OnBnClickedCloseSelfprocess()
{
// TODO: 在此添加控件通知处理程序代码
RaisePrivileges();
ExitProcess(0);
}