在Windows系统中,应用程序都以进程的形式存在于内存中。当运行一个程序的时候,操作系统就会将这个程序装入内存,并分配各种运行程序所需的资源,为进程创建主线程。
系统也提供了任务管理器,可供我们使用。管理进程的界面如下:
其中包含的内容一目了然,就没有必要讲解了。直接进入常用API。
1. 进程的创建
UINT WinExec(
LPCSTR lpCmdLine,//指向一个可执行文件
UINT uCmdShow//程序运行后的窗口状态
/*
SW_SHOW:表示程序运行后,窗口为显示状态
SW_HIDE:表示程序运行后,窗口为隐藏状态
*/
);
BOOL CreateProcess(
LPCTSTR lpApplicationName,//指定可执行文件的文件名
LPTSTR lpCommandLine,//指定欲传给新进程的命令行参数
LPSECURITY_ATTRIBUTES lpProcessAttributes,//进程安全属性,通常为NULL,表示默认安全属性
LPSECURITY_ATTRIBUTES lpThreadAttributes,//线程安全属性,通常为NULL,表示默认安全属性
BOOL bInheritHandles,//指定当前进程中的可继承句柄是否被新进程继承
DWORD dwCreationFlags,//指定新进程的优先级以及其他创建标志
LPVOID lpEnvironment,//指定新进程环境变量,通常指定为NULL值
LPCTSTR lpCurrentDirectory,//指定新进程使用的当前目录
LPSTARTUPINFO lpStartupInfo,//指向指定新进程启动信息的结构体
LPPROCESS_INFORMATION lpProcessInformation//指向用于返回新进程和主线程的相关信息的结构体。
);
2. 进程的结束
BOOL TerminateProcess(
HANDLE hProcess,//与结束进程的进程句柄
UINT uExitCode//进程的退出码,通常为0
);
3. 进程的枚举
HANDLEWINAPI CreateToolhelp32Snapshot(
DWORD dwFlags,//指明要建立系统快照的类型。
/*
TH32CS_SNAPMODULE:枚举进程中DLL时指定
TH32CS_SNAPPROCESS:枚举系统中进程时指定
TH32CS_SNAPTHREAD:在枚举系统中线程时指定
*/
DWORD th32ProcessID//该参数根据dwFlags参数的不同而不同。如果枚举的是系统中的进程或线程,则为NULL;如果枚举的是进程中加载的DLL,则参数是进程ID。
);
BOOL WINAPI Process32First(
HANDLE hSnapshot,//该参数为上面函数返回的快照句柄
LPPROCESSENTRY32 lppe//指向结构体的指针,在使用该结构体时,需要对该结构体的变量dwSize进行赋值。
);
BOOL WINAPI Process32Next(
HANDLE hSnapshot,//和上面一样,是快照句柄
LPPROCESSENTRY32 lppe//依然和上面一样
);
若函数取到下一个进程则返回true,否则返回ERROR_NO_MORE_FILES。
4. 进程的暂停
DWORD SuspendThread(
HANDLE hThread//要暂停线程的句柄
);
所谓暂停进程,就是暂停进程中的所有线程。
线程句柄的获得:
HANDLE OpenThread(
DWORD dwDesiredAccess,//打开线程欲获得的访问权限,为了方便可以设置为THREAD_ALL_ACCESS
BOOL bInheritHandle,//指定获取的句柄是否可以继承,一般设置为FALSE
DWORD dwThreadId//线程ID
);
有时候不得不让进程处于暂停运行的状态。例如,病毒有两个运行的进程,它们之间不断地相互检测,当一个病毒进程发现另一个病毒进程被结束了,那么它会再次把那个结束的病毒进程启动。由于病毒进程互相检测频率较高,因此很难把两个病毒进程结束掉,而需要先暂停这两个进程,然后再结束它们。
5. 进程的恢复
DWORD ResumeThread(
HANDLE hThread//与SuspendThread函数的参数用法相同
);
有了前面的API,我们就可以做一些事情了。可以自己设计一个进程管理的软件,实现系统中进程的枚举,进程中DLL的枚举,进程的暂停、恢复和结束等。是的,按照国际惯例,我已准备好了我的实现代码供小伙伴们参考。
界面大致如下://枚举进程
void CProcessManagerDlg::ShowProcess()
{
//清空列表框内容
m_ListProcess.DeleteAllItems();
//创建进程快照
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap == INVALID_HANDLE_VALUE)
{
AfxMessageBox(_T("Create Toolhelp32 Snapshot Error"));
return;
}
PROCESSENTRY32 Pe32 = { 0 };
Pe32.dwSize = sizeof(PROCESSENTRY32);
BOOL bRet = Process32First(hSnap, &Pe32);
int i = 0;
CString str;
//循环获取进程快照中的每一项
while(bRet)
{
m_ListProcess.InsertItem(i, Pe32.szExeFile);
str.Format(_T("%d"),Pe32.th32ProcessID);
m_ListProcess.SetItemText(i, 1, str);
++i;
bRet = Process32Next(hSnap, &Pe32);
}
CloseHandle(hSnap);
}
//获取选中进程的PID
int CProcessManagerDlg::GetSelectPid()
{
//选择进程的索引
POSITION Pos = m_ListProcess.GetFirstSelectedItemPosition();
int nSelect = -1;
while (Pos)
{
nSelect = m_ListProcess.GetNextSelectedItem(Pos);
}
if (-1 == nSelect)
{
AfxMessageBox(_T("请选择要枚举DLL的进程"));
return 0;
}
//获取选择的进程ID
char szProcessID[MAXBYTE] = { 0 };
m_ListProcess.GetItemText(nSelect, 1, (LPTSTR)szProcessID, MAXBYTE);
CString str;
str.Format(_T("%s"), szProcessID);
//AfxMessageBox(str);
int iRet = _ttoi(str);
return iRet;
}
//显示对应进程中加载的DLL
void CProcessManagerDlg::OnBnClickedShowmodule()
{
//清空列表框内容
m_ListModule.DeleteAllItems();
//获取选中的进程ID号
intnPid = GetSelectPid();
//CString s;
//s.Format(_T("%d"), nPid);
//AfxMessageBox(s);
//进程ID为0,则返回
if(nPid == 0)
{
return;
}
MODULEENTRY32 Me32 = { 0 };
Me32.dwSize = sizeof(MODULEENTRY32);
//创建模块快照
HANDLEhSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, nPid);
if(hSnap == INVALID_HANDLE_VALUE)
{
AfxMessageBox(_T("Create Toolhelp32Snapshot Error"));
return;
}
BOOLbRet = Module32First(hSnap, &Me32);
inti = 0;
CStringstr;
//循环获取模块快照中的每一项
while(bRet)
{
m_ListModule.InsertItem(i, Me32.szModule);
m_ListModule.SetItemText(i, 1, Me32.szExePath);
++i;
bRet = Module32Next(hSnap, &Me32);
}
CloseHandle(hSnap);
}
//结束对应的进程
void CProcessManagerDlg::OnBnClickedEndprocess()
{
int nPid = GetSelectPid();
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, nPid);
if (hProcess == NULL)
{
return;
}
BOOL bRet = TerminateProcess(hProcess, 0);
if (bRet == TRUE)
{
AfxMessageBox(_T("进程结束成功"));
}
CloseHandle(hProcess);
return;
}
//暂停对应的进程
void CProcessManagerDlg::OnBnClickedStopprocess()
{
int nPid = -1;
nPid = GetSelectPid();
if (nPid == 0)
{
return;
}
//创建线程快照
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, nPid);
if (hSnap == INVALID_HANDLE_VALUE)
{
AfxMessageBox(_T("Create Toolhelp32 Snapshot Error"));
return;
}
THREADENTRY32 Te32 = {0};
Te32.dwSize = sizeof(THREADENTRY32);
BOOL bRet = Thread32First(hSnap, &Te32);
//循环获得线程快照中的每一项
while (bRet)
{
//得到属于选择进程的线程
if (Te32.th32OwnerProcessID == nPid)
{
//打开线程
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS,
FALSE, Te32.th32ThreadID);
//暂停线程
SuspendThread(hThread);
CloseHandle(hThread);
}
bRet = Thread32Next(hSnap, &Te32);
}
CloseHandle(hSnap);
}
//恢复对应的进程
void CProcessManagerDlg::OnBnClickedResume()
{
int nPid = -1;
nPid = GetSelectPid();
if (nPid == 0)
{
return;
}
//创建线程快照
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, nPid);
if (hSnap == INVALID_HANDLE_VALUE)
{
AfxMessageBox(_T("Create Toolhelp32 Snapshot Error"));
return;
}
THREADENTRY32 Te32 = { 0 };
Te32.dwSize = sizeof(THREADENTRY32);
BOOL bRet = Thread32First(hSnap, &Te32);
//循环获得线程快照中的每一项
while (bRet)
{
//得到属于选择进程的线程
if (Te32.th32OwnerProcessID == nPid)
{
//打开线程
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS,
FALSE, Te32.th32ThreadID);
//恢复线程
ResumeThread(hThread);
CloseHandle(hThread);
}
bRet = Thread32Next(hSnap, &Te32);
}
CloseHandle(hSnap);
}
//打开进程
void CProcessManagerDlg::OnBnClickedOpen()
{
AddProcess process;
process.DoModal();
AfxMessageBox(process.m_CodeLocation);
AfxMessageBox(process.m_CodeName);
//判断输入是否完整
if (process.m_CodeLocation.GetLength() > 0 &&
process.m_CodeName.GetLength() > 0)
{
PROCESS_INFORMATION pi = { 0 };
STARTUPINFO si = { 0 };
si.cb = sizeof(STARTUPINFO);
CString file = process.m_CodeLocation +”\”+ process.m_CodeName;
BOOL bRet = CreateProcess(file, NULL, NULL, NULL, FALSE,
NULL, NULL, NULL, &si, &pi);
if (bRet == FALSE)
{
AfxMessageBox(_T("Create Process Error"));
return;
}
ShowProcess();
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return;
}
else
{
AfxMessageBox(_T("请输入完整内容!"));
}
return;
}
温馨提示:有些操作如果没有成功可能是当前进程的权限不够,可以尝试提高进程的系统权限。