27.实现一个简单的任务管理器

①、设计界面、以及列表控件变量的绑定;
控件:List Control
singleselection:True
view:report
绑定控件变量:m_TaskList
②、列表控件样式的指定:

m_TaskList.SetExtendedStyle(LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT);//设置列表视图控件的当前扩展样式
	m_TaskList.InsertColumn(0, _T("进程名称"),2,100);
	m_TaskList.InsertColumn(1, _T("PID"), 2, 60);
	m_TaskList.InsertColumn(2, _T("文件路径"), 2, 380);

③进程的获取

#include <Tlhelp32.h>
#include <Psapi.h>
#pragma comment(lib, "Psapi.lib")
BOOL CMFCApplication17Dlg::GetProcessList()//获取进程列表
{
	BOOL bResult = FALSE;
	HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	//拍摄指定进程以及这些进程使用的堆,模块和线程的快照,必须包含头文件Tlhelp32.h
	if (hSnap == INVALID_HANDLE_VALUE)
		return FALSE;

	int idx = 0;
	CString strID;
	HANDLE hProcess = NULL;
	PROCESSENTRY32 info = { 0 };//PROCESSENTRY32是一个结构
	info.dwSize = sizeof(PROCESSENTRY32);//进程的大小

	BOOL bRet = Process32First(hSnap, &info);//检索有关系统快照中遇到的第一个进程的信息
	while (bRet) {
		idx = m_TaskList.InsertItem(m_TaskList.GetItemCount(), _T(""));//返回新项的索引
		//不清楚m_TaskList.GetItemCount()为什么逐次增加而不是固定大小
		m_TaskList.SetItemText(idx, 0, info.szExeFile);//info.szExeFile是进程的可执行文件的名称
		strID.Empty();
		strID.Format(_T("%d"), info.th32ProcessID);//获取进程ID
		m_TaskList.SetItemText(idx, 1, strID);

		hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, info.th32ProcessID);//获取进程句柄
		if (hProcess) {
			TCHAR szPath[MAX_PATH] = { 0 };
			GetModuleFileNameEx(hProcess, NULL, szPath, MAX_PATH);
			//检索包含指定模块的文件的标准路径,必须包含头文件psapi.h
			m_TaskList.SetItemText(idx, 2, szPath);
		}
		bRet = Process32Next(hSnap, &info); //检索有关系统快照中遇到的下一个进程的信息
		printf("%d\n", idx);

	}
	return TRUE;
}

④、Debug 权限提升函数:(目前没作用)
BOOL AdjustPrivileges()
{
HANDLE hToken = NULL;
TOKEN_PRIVILEGES tp = {0};
TOKEN_PRIVILEGES oldtp = {0};
DWORD dwSize = sizeof(TOKEN_PRIVILEGES);
LUID luid = {0};

if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
	if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
		return TRUE;
	else
		return FALSE;
}
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {
	CloseHandle(hToken);
	return FALSE;
}

tp.PrivilegeCount=1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

/* Adjust Token Privileges */
if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &oldtp, &dwSize)) {
	CloseHandle(hToken);
	return FALSE;
}

// close handles
CloseHandle(hToken);
return TRUE;

}

⑤、菜单资源的添加及编辑:
刷新列表:ID_M_REFRESH_LIST
结束此进程:ID_M_EDN_TASK
定位文件:ID_M_FIND_EXE
拷贝路径:ID_M_COPY_PATH

⑥、菜单资源的弹出:

void CMFCApplication17Dlg::OnNMRClickListPath(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
	
	//点击行的索引
	if (pNMItemActivate->iItem < 0) return;

	CString strID = m_TaskList.GetItemText(pNMItemActivate->iItem, 1);//获取PID

	CPoint pt;
	GetCursorPos(&pt);//获取游标(鼠标的位置)
	CMenu mMenu, *pMenu;
	mMenu.LoadMenu(IDR_MENU);//加载菜单
	pMenu = mMenu.GetSubMenu(0);//获取子菜单
	if (strID == _T("0") || strID == _T("4")) //PID=0,4是系统进程,后面三项禁用
	{
		pMenu->EnableMenuItem(ID_M_EDN_TASK, MF_BYCOMMAND | MF_GRAYED);//禁用
		pMenu->EnableMenuItem(ID_M_FIND_EXE, MF_BYCOMMAND | MF_GRAYED);
		pMenu->EnableMenuItem(ID_M_COPY_PATH, MF_BYCOMMAND | MF_GRAYED);
	}
	pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, this);//弹出菜单

	
	// TODO: 在此添加控件通知处理程序代码
	*pResult = 0;
}

⑦、菜单响应函数的实现:

void CMFCApplication17Dlg::OnMRefreshList()//刷新列表功能
{
	
	for (int idx = 0; idx < m_ImgList.GetImageCount(); idx++) {
		m_ImgList.Remove(idx);
	}

	m_TaskList.DeleteAllItems();//先删除所有内容
	GetProcessList();//重新获取进程列表
	// TODO: 在此添加命令处理程序代码
}


void CMFCApplication17Dlg::OnMEdnTask()//结束此进程功能
{
	int idx = m_TaskList.GetSelectionMark();//检索列表视图控件的选择标记。(行)
	CString strID = m_TaskList.GetItemText(idx, 1);
	CString strName = m_TaskList.GetItemText(idx, 0);

	int iRet = MessageBox(_T("您确定要结束 ") + strName + _T(" 吗?"), _T("友情提示"), MB_OKCANCEL);
	if (iRet == IDCANCEL) return;

	if (strID == _T("0") || strName == _T("4")) { //实际上这个位置的判断是多余的
		MessageBox(_T("系统进程,无法结束!"), _T("提示"));
	}
	else {
		BOOL bRet = FALSE;
		HANDLE hProcess = OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION, FALSE, _tstoi(strID));
		if (hProcess != NULL) {
			bRet = TerminateProcess(hProcess, -1);//结束进程
			CloseHandle(hProcess);//关闭打开的对象句柄。
		}

		if (!bRet) {
			MessageBox(_T("结束进程 \" ") + strName + _T(" \" 失败,请重试!"), _T("提示"));
		}
		else {
			m_TaskList.DeleteItem(idx);//删除当前行
		}
	}
	// TODO: 在此添加命令处理程序代码
}



void CMFCApplication17Dlg::OnMFindExe()
{
	int idx = m_TaskList.GetSelectionMark();
	CString strPath = m_TaskList.GetItemText(idx, 2);
	if (strPath.GetLength() > 0)
		ShellExecute(m_hWnd, _T("open"), _T("Explorer.exe"), _T("/select,") + strPath, NULL, SW_SHOW);//对指定文件进行打开操作
	// TODO: 在此添加命令处理程序代码
}



void CMFCApplication17Dlg::OnMCopyPath()//拷贝路径
{
	int idx = m_TaskList.GetSelectionMark();
	CString strPath = m_TaskList.GetItemText(idx, 2);

	if (!OpenClipboard()) return;//打开剪切板
	if (!EmptyClipboard()) {
		CloseClipboard();//关闭剪切板
		return;
	}

	size_t cbStr = (strPath.GetLength() + 1) * sizeof(TCHAR);
	HGLOBAL hData = GlobalAlloc(GMEM_MOVEABLE, cbStr);//从堆中分配指定的字节数
	memcpy_s(GlobalLock(hData), cbStr, strPath.LockBuffer(), cbStr);
	GlobalUnlock(hData);
	strPath.UnlockBuffer();

	UINT uiFormat = (sizeof(TCHAR) == sizeof(WCHAR)) ? CF_UNICODETEXT : CF_TEXT;
	if (::SetClipboardData(uiFormat, hData) == NULL) //以指定的剪贴板格式将数据放置在剪贴板上
	{
		MessageBox(_T("设置剪贴板数据失败!"));
		CloseClipboard();
		return;
	}

	CloseClipboard();
	// TODO: 在此添加命令处理程序代码
}

⑧、为列表控件加上程序的前缀图标:
// H 头文件中进行图像列表的定义:
CImageList m_ImgList;

// OnInitDialog() 函数中进行图像列表的创建及设置:
m_ImgList.Create(16, 16, ILC_COLOR24, 10, 10);
m_TaskList.SetImageList(&m_ImgList, LVSIL_SMALL);

⑨、修改GetProcessList()函数为如下:

BOOL CMFCApplication17Dlg::GetProcessList()//获取进程列表
{
	BOOL bResult = FALSE;
	HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	//拍摄指定进程以及这些进程使用的堆,模块和线程的快照,必须包含头文件Tlhelp32.h
	if (hSnap == INVALID_HANDLE_VALUE)
		return FALSE;

	int idx = 0;
	int imgIdx=-1;
	CString strID;
	HANDLE hProcess = NULL;
	CString strPath, strSys(_T("SystemRoot"));
	PROCESSENTRY32 info = { 0 };//PROCESSENTRY32是一个结构
	info.dwSize = sizeof(PROCESSENTRY32);//进程的大小

	BOOL bRet = Process32First(hSnap, &info);//检索有关系统快照中遇到的第一个进程的信息
	
	while (bRet) {
		hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, info.th32ProcessID);//获取进程句柄
		if (hProcess)
		{
			strPath.Empty();
			GetModuleFileNameEx(hProcess, NULL, strPath.GetBufferSetLength(MAX_PATH), MAX_PATH);
			//检索包含指定模块的文件的标准路径,必须包含头文件psapi.h
			strPath.ReleaseBuffer();
			strPath.TrimLeft(_T("\\?"));
			if (strPath.Left(strSys.GetLength()).CompareNoCase(strSys) == 0)
			{
				TCHAR szWin[MAX_PATH] = { 0 };
				GetWindowsDirectory(szWin, MAX_PATH);//获取Windows路径
				strPath.Replace(strSys, szWin);
			}

			SHFILEINFO shInfo = { 0 };
			SHGetFileInfo(strPath, 0, &shInfo, sizeof(SHFILEINFO), SHGFI_SMALLICON | SHGFI_ICON);//获取图标
			imgIdx = m_ImgList.Add(shInfo.hIcon);//加入图标的位置
		}

		//进行列表项的插入
		idx = m_TaskList.InsertItem(m_TaskList.GetItemCount(), _T(""), imgIdx);//返回新项的索引
		m_TaskList.SetItemText(idx, 0, info.szExeFile);
		strID.Empty();
		strID.Format(_T("%d"), info.th32ProcessID);
		m_TaskList.SetItemText(idx, 1, strID);
		m_TaskList.SetItemText(idx, 2, strPath);

		//继续遍历进程列表
		bRet = Process32Next(hSnap, &info);//检索有关系统快照中遇到的下一个进程的信息
	}
	return TRUE;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
据国外研究公司统计,在2008年全球个人计算机用户已经超过10亿,并预测在2010年全球个人计算机用户数量将超过13亿。随着个人计算机走进千家万户,计算机操作系统中的任务管理器也被越来越多的用户所熟悉和使用。 任务管理器是在Windows系统中管理应用程序和进程的工具,通常由Windows操作系统自带,也有提供增强功能的第三方软件。通过任务管理器用户可以方便的查看当前运行的程序、进程、用户、网络连接以及系统对内存和CPU的资源占用,并可以强制结束某些程序和进程,此外还可以监控系统资源的使用状况。 Windows 任务管理器首次出现是在1998年美国微软公司发行的Windows98操作系统中,此后微软的各个版本的Windows操作系统都集成了任务管理器任务管理器并不是Windows系统的专利,它广泛运用于各种操作系统中,在苹果公司的Mac OS 操作系统中有类似的活动监视器(Activity Monitor),在基于Linux的ubuntu操作系统有相类似功能的系统监视器。 Windows任务管理器提供了有关计算机性能的信息,并显示了计算机上所运行的程序和进程的详细信息;如果连接到网络,那么还可以查看网络状态并迅速了解网络是如何工作的。它的用户界面提供了文件、选项、查看、窗口、关机、帮助等六大菜单项,其下还有应用程序、进程、性能、联网、用户等五个标签页。 课题设计就是模拟Windows任务管理器,开发的一个Windows进程管理软件。主要设计的是一个基于窗体的C#程序,在主对话框上面放置了一个标签控件,并创建了应用程序、进程和性能三个页面,标签控件用于选择并显示页面。三个页面分别用于显示当前运行的窗口程序、进程及进程模块、系统资源使用情况。程序还实现了结束任务、等对进程管理的基本功能。在的设计过程中,通过调用Windows API函数而获得任务、进程、线程模块,以及系统资源使用情况等信息。最后在Windows10系统上进行测试,实现了进程管理的基本功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值