Windows进程控制

在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;
}

温馨提示:有些操作如果没有成功可能是当前进程的权限不够,可以尝试提高进程的系统权限。



  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值