vc++基础班[27]---实现一个简单的任务管理器

因为任务管理器中涉及到进程的枚举操作,所以把两节课的知识点合并到一起来讲!

①、设计界面、以及列表控件变量的绑定;

②、列表控件样式的指定:

m_TaskList.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);

m_TaskList.InsertColumn(0, _T(" 进程名称"), 0, 100);

m_TaskList.InsertColumn(1, _T(" PID"), 0, 60);

m_TaskList.InsertColumn(2, _T(" 文件路径"), 0, 380);

③、进程列表的获取:

具体的方法也是多种的,具体见:http://www.cctry.com/thread-11857-1-1.html

这里面我们使用第一种方法给大家讲解:

#include <Tlhelp32.h>

#include <Psapi.h>

#pragma comment(lib, "Psapi.lib")

BOOL CMFCTestDlg::GetProcessList()

{

BOOL bResult = FALSE;

HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if ( hSnap == INVALID_HANDLE_VALUE )

return FALSE;

int idx = 0;

CString strID;

HANDLE hProcess = NULL;

PROCESSENTRY32 info = {0};

info.dwSize = sizeof(PROCESSENTRY32);

BOOL bRet = Process32First(hSnap, &info);

while(bRet) {

idx = m_TaskList.InsertItem(m_TaskList.GetItemCount(), _T(""));

m_TaskList.SetItemText(idx, 0, info.szExeFile);

strID.Empty();

strID.Format(_T("%d"), info.th32ProcessID);

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);

m_TaskList.SetItemText(idx, 2, szPath);

}

bRet = Process32Next(hSnap, &info);

}

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 CMFCTestDlg::OnNMRClickTaskList(NMHDR *pNMHDR, LRESULT *pResult)

{

LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);

if ( pNMItemActivate->iItem < 0 ) return;

CString strID = m_TaskList.GetItemText(pNMItemActivate->iItem, 1);

CPoint pt;

GetCursorPos(&pt);

CMenu mMenu, *pMenu;

mMenu.LoadMenu(IDR_MENU);

pMenu = mMenu.GetSubMenu(0);

if (strID == _T("0") || strID == _T("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);

*pResult = 0;

}

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

void CMFCTestDlg::OnMRefreshList()

{

for (int idx = 0; idx < m_ImgList.GetImageCount(); idx++) {

m_ImgList.Remove(idx);

}

m_TaskList.DeleteAllItems();

GetProcessList();

}

void CMFCTestDlg::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);

}

}

}

void CMFCTestDlg::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);

}

void CMFCTestDlg::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();

}

⑧、为列表控件加上程序的前缀图标:

// H 头文件中进行图像列表的定义:

CImageList m_ImgList;

// OnInitDialog() 函数中进行图像列表的创建及设置:

m_ImgList.Create(16, 16, ILC_COLOR24, 10, 10);

m_TaskList.SetImageList(&m_ImgList, LVSIL_SMALL);

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

BOOL CMFCTestDlg::GetProcessList()

{

BOOL bResult = FALSE;

HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if ( hSnap == INVALID_HANDLE_VALUE )

return FALSE;

int idx = 0, imgIdx = -1;

CString strID;

HANDLE hProcess = NULL;

CString strPath, strSys(_T("SystemRoot"));

PROCESSENTRY32 info = {0};

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);

strPath.ReleaseBuffer();

strPath.TrimLeft(_T("\\?"));

if (strPath.Left(strSys.GetLength()).CompareNoCase(strSys) == 0){

TCHAR szWin[MAX_PATH] = {0};

GetWindowsDirectory(szWin, MAX_PATH);

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;

}

1、使用 EnumProcesses 函数进行进程的枚举;

2、针对选中多个进程进行结束时的处理!

时间: 2024-07-30 08:55:22

vc++基础班[27]---实现一个简单的任务管理器的相关文章

vc++基础班[26]---进程的相关操作

①.ShellExecute 进行进程的创建,属于 shell api: //int iRet = (int)ShellExecute(m_hWnd, _T("open"), _T("NOTEPAD.EXE"), _T("C:\\123.txt"), NULL, SW_SHOW); int iRet = (int)ShellExecute(m_hWnd, _T("open"), _T("C:\\WINDOWS\\NO

vc++基础班[24]---系统各种路径信息的获取

------------------------------------------ Begin ---------------------------------------- ①.Windows.System32.temp 等目录的获取: TCHAR szPath[MAX_PATH] = {0}; GetSystemDirectory(szPath, MAX_PATH); //C:\WINDOWS\system32 GetWindowsDirectory(szPath, MAX_PATH);

vc++基础班[28]---动态数组及动态链表的讲解

C++中也有相应的动态数组.动态链表.映射表的模板类,就是STL中的:vector.list.map 他们属于C++标准中的一部分,对于程序的移植性来说也是不错的,但是在MFC编程中使用 CArray.CList.CMap 会更方便一些! CArray.CList.CMap 的由来?…… ①.数组的基本说明: 数组是固定大小的,相同数据类型的元素的顺序集合,每个元素在数组中有一个固定的位置. 将10个数放入数组中,假设数组的名称为number,可以称数组中第一个元素为 number[0],第二个

vc++基础班[23]---文件夹的基本操作

①.文件夹的创建:CreateDirectory ※※※ 注意:此函数只能创建一层目录,比如想在 C 盘下的 Temp 目录下创建新目录为:123 那么前提是 Temp 这个目录存在才可以! ②.文件夹的删除:RemoveDirectory ※※※ 注意:此函数只能删除一个空的目录,如果目录中有子目录或子文件的话会删除失败的! 解决的方法是用 递归的思想,调用上节课给大家讲解的文件删除函数将子文件删除,之后就可以调用此函数删除一个空的文件夹了: ③.文件夹属性信息的获取:GetFileAttri

vc++基础班[25]---系统信息的获取

--------------------------------------------------------------------------- VC 驿站 WwW.CcTry.CoM 多抽出一分钟时间来学习,让你的生命更加精彩! C.C++.VC++ 各种学习资源,免费教程,期待您的加入! 动画教程只是起到技术交流的作用,请大家不用利用此方法做非法用途. 由此动画造成的任何后果和动画作者及本站无关. --------------------------------------------

vc++基础班[21]---文件的基本操作之CFile

①.文件的创建.打开.关闭: 文件的创建.打开:CFile::Open 文件的关闭:CFile::Close CFile::modeCreate:以新建方式打开,如果文件不存在,则新建:如果文件已存在,把该文件长度置零,即清除文件原有内容: CFile::modeNoTruncate:以追加方式打开,如果文件存在,打开并且不将文件长度置零,如果文件不存在,会抛出异常. 一般与CFile::modeCreate一起使用,则文件不存在时,新建一个文件:存在就进行追加操作: CFile::modeRe

vc++基础班[22]---文件的基本操作2

MFC 中的 CFile 及其派生类中没有提供直接进行文件的复制操作,因而要借助于SDK API: SDK中的文件相关函数常用的有CopyFile().CreateDirectory().DeleteFile().MoveFile() ①.文件的复制:CopyFile 若要复制文件夹,可以在目标位置新建一文件夹,然后将源文件夹里面的文件进行遍历,一个一个的复制到目标文件夹内即可! ②.文件的重命名或移动 [适用于文件夹]: static CFile::Rename 重命名文件: MoveFile

运用基础班知识做一个网页

一个网页,首先得有框架,然后各种样式各种动态.就好像老师说的一间房子,要刷漆(css),还要买电器(javascript).现在开始装修我们的房子吧! html超文本标记语言(给网页写内容,超文本指的就是网页上不光有文本,还有图片,音乐,视频等), css层叠样式表(添加各种样式效果,其中最主要的是浮动,因为div是块元素,独占一行,而浮动能把div排成一行.) javascript(直译式脚本语言,给网页增加动态效果,实例:表单验证,网页特效,小游戏等,) jquery(快速简洁的javasc

PHP基础班初学感悟

不知不觉差不多一个月就过去了 刚到培训班那时候的心情,现在也还能有所感觉 作为今年6月份的毕业生,刚从大学的实习期出来,辞掉了上一份工作,本来是打算找一份更加与专业挂钩的工作做的 也许是90后对网络的情有独钟,亦或者是因为IT行业目前的高薪诱惑,毅然而然地踏上了转行的路程 基础班,说难不难,都是很基础的东西,还不到深的,难的东西 这是我们讲课老师说的 我也感觉差不多 不过作为一名零基础入门的牛犊,难免会有点心慌 而这段时间的学习也让我更加明白,用心的重要性 还有坚持,毅力 上课期间曾经因为一次重