优秀的毕业设计论文网
计算机 JAVA 电子信息 单片机 机械机电 模具 土木工程 建筑结构 论文
热门搜索词:网络 ASP.NET 汽车 电气 数控 PLC

Windows进程管理工具设计与实现

以下是资料介绍,如需要完整的请充值下载.
1.无需注册登录,支付后按照提示操作即可获取该资料.
2.资料以网页介绍的为准,下载后不会有水印.资料仅供学习参考之用.
  
资料介绍:

Windows进程管理工具设计与实现
摘  要
Windows自带的任务管理器存在功能上的缺陷,如不能查看进程的模块及线程信息。该课题设计就是模拟Windows任务管理器,开发一个功能更完善的Windows进程管理软件。主要设计的是一个基于对话框的VC++程序,在主对话框上面放置了一个标签控件,并创建了任务、进程和系统信息三个页面,标签控件用于选择并显示页面。三个页面分别用于显示当前运行的窗口程序、进程及进程模块、系统资源使用情况。程序还实现了结束任务、切换任务、终止进程等对进程管理的基本功能。在程序的设计过程中,通过调用Windows API函数而获得任务、进程、线程模块,以及系统资源使用情况等信息。最后在Windows XP系统上进行测试,实现了进程管理的基本功能,为用户了解当前进程及系统资源使用情况提供了很好的参考。

[资料来源:THINK58.com]

关键词:任务管理器;线程;进程;API
目  录
论文总页数:21页 内容来自think58 [来源:http://think58.com]

1 引言 1
1.1 课题背景 1
1.2 国内外研究现状 1
1.3 本课题研究的意义 1
1.4 本课题的研究方法 1
1.5 进程与线程简介 1
1.5.1 进程简介 1
1.5.2 线程简介 3
1.5.3 进程与线程的关系 3
1.5.4 Windows自带的任务管理器分析 4
2 主要功能及设计思路 5
2.1 主要功能 5
2.2 设计思路 5
3 详细设计 5
3.1 主框架的实现 6
3.1.1 子对话框的显示 6
3.1.2 实现菜单 7
3.1.3 提升本程序权限 8
3.2 任务列表页面设计 8
3.2.1 显示任务信息 8
3.2.2 结束任务 10
3.2.3 切换任务 11
3.3 进程列表页面设计 11
3.3.1 显示进程信息 12
3.3.2 显示模块及线程信息 14
3.3.3 结束进程 15
3.3.4 删除文件 16
3.3.5 保存进程信息到文件 16
3.4 系统性能页面设计 17
3.4.1 绘制CPU使用率图 17
3.4.2 绘制内存使用率图 17 think58.com [资料来源:http://www.THINK58.com]
3.4.3 其他性能显示 17
3.4.4 系统信息显示 17
4 测试结果 18
结    论 19
参考文献 19
致    谢 20
声    明 21
 
1.5.2 线程简介
线程是一个进程内的基本调度单位,它既可以由操作系统内核控制,也可由用户程序控制。
线程是由两个部分组成的:一个是线程的内核对象,操作系统用它来对线程实施管理。内核对象也是系统用来存放线程统计信息的地方。另一个是线程堆栈,它用于维护线程在执行代码时需要的所有函数参数和局部变量
线程只由相关的堆栈(系统栈或用户栈)、寄存器和线程控制表TCB组成。寄存器可被用来存储线程内的局部变量,但不能存储其它线程的相关变量。
线程也有三个基本状态:执行状态、就绪状态和阻塞状态。针对线程的三种基本状态,存在五种基本操作来转换线程的状态。这五种基本操作是:
1、派生:线程在进程内派生出来,它既可由进程派生,也可由线程派生。
2、阻塞:如果一个线程在执行过程中需要等待某个事件发生,则被阻塞。
3、激活:如果阻塞线程的事件发生,则该线程被激活并进入就绪队列。
4、调度:选择一个就绪线程进入执行状态。 think58

[资料来源:http://THINK58.com]

5、结束:如果一个线程执行结束,它的寄存器上下文以及堆栈内容等将被释放。
1.5.3 进程与线程的关系
进程是不活泼的。若要使进程完成某项操作,它必须拥有一个在它的环境中运行的线程,该线程负责执行包含在进程的地址空间中的代码。实际上,单个进程可能包含若干个线程,所有这些线程都“同时”执行进程地址空间中的代码。
线程与资源分配无关,它属于某一个进程,并与进程内的其它线程一起共享进程的资源。当进程发生调度时,不同的进程拥有不同的虚拟地址空间,而同一进程内的不同线程共享同一地址空间。为此,每个线程都有它自己的一组CPU寄存器和它自己的堆栈。每个进程至少拥有一个线程,来执行进程的地址空间中的代码。如果没有线程来执行进程的地址空间中的代码,那么进程就没有存在的理由了,系统就将自动撤消该进程和它的地址空间。
若要使所有这些线程都能运行,操作系统就要为每个线程安排一定的CPU时间。它通过以一种循环方式为线程提供时间片(称为量程),造成一种假象,仿佛所有线程都是同时运行的一样。图3显示了在单个CPU的计算机上是如何实现这种运行方式的。如果计算机拥有多个CPU,那么操作系统就要使用复杂得多的算法来实现CPU上线程负载的平衡。
当创建一个进程时,系统会自动创建它的第一个线程,称为主线程。然后,该线程可以创建其他的线程,而这些线程又能创建更多的线程。 think58
[资料来源:http://www.THINK58.com]

1.5.4 Windows自带的任务管理器分析
Windows任务管理器由性能、进程、应用程序三大部分组成。其实这三大部分是有机的联系在一起的,尤其是性能和进程,性能中除了CPU使用率以外,其余的数据都是由进程模块顺便取得的。
Windows2000/XP的任务管理器通过 NtQuerySystemInformation 的调用来获取各类信息,如CPU使用率,内存使用率,句柄总数,线程总数,进程总数等等。在任务管理器中的几乎所有信息都是来自该函数。NtQuerySystemInformation函数隶属Ntdll.dll,是一个未公开的函数。其调用方式为:
NTSTATUS NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS
 SystemInformationClass,PVOID SystemInformation,
 ULONG SystemInformationLength,PULONG
 ReturnLength);
SystemInformationClass:在SYSTEM_INFORMATION_CLASS中的枚举值之一, 声明返回信息的种类;
SystemInformation:指到一个要求返回信息的缓冲区,这个系统信息变量的尺寸和结构依赖于SystemInformationClass参数的值;
SystemInformationLength:SystemInformation参数指定的缓冲区尺寸;
ReturnLength:返回值尺寸。
这个函数是一个正在修改的函数,在Windows2000和Windows XP中可用,但在Windows 98和Windows Me中不可用。而且该函数调用的入口参数非常之多,调用复杂。因此,在我的这个进程管理器的开发中,我将使用其它方法来获取各类信息。

copyright think58 [资料来源:THINK58.com]


2 主要功能及设计思路
2.1 主要功能
本设计要求实现的主要功能——进程管理功能,具体包括以下内容:
(1)任务管理:列出所有当前运行的窗口程序名、运行状态等信息;对它们进行终止、切换等操作。
(2)进程管理:列出所有的Windows进程,以及进程所在的磁盘绝对路径,进程消耗资源状况等;列出所有进程的相关模块挂载名,模块所在磁盘的绝对路径以及进程的线程情况,包括资源占用情况、所在内存空间地址等;除核心进程外,所有的其他进程均可以被终止,能够尽量不丢失信息,在提升本管理进程级别后,也能够对系统的核心进程终止。;
(3)系统性能显示:绘制CPU、内存使用率图,以描述系统性能;列出物理内存、虚拟内存和页文件的使用情况;显示系统当前信息,包括系统名、计算机名和用户名等。
2.2 设计思路
在Visual C++ 6.0环境设计一个基于对话框的应用程序,类似于Windows自带的任务管理器,主窗口上添加一个标签控件,加入三个页面,分别是:任务、进程和系统性能信息。
其中,任务页面显示当前正在运行的任务(可见且有窗口标题),用列表控件进行显示,并能够对任务进行操作,如:添加新任务,结束任务,切换任务等。
进程页面显示当前系统正在运行的进程及相关的模块,线程等,用列表控件进行显示,并能够实行终止进程、进程列表保存到文件等操作。

内容来自think58

[资料来源:THINK58.com]


系统性能页面显示物理内存、虚拟内存和页文件等详细使用情况,CPU、内存的使用率,并绘制CPU使用率和内存使用率的图形,并用列表控件显示系统当前信息(系统名、计算机名和当前用户等)。
3 详细设计
程序主界面如图2。
  think58好,好think58 [来源:http://think58.com]


图2  主界面
3.1 主框架的实现
本程序是基于对话框的程序。首先创建一个基于对话框的应用程序PcsMgr.exe, 在主对话框类PcsMgrDlg中添加一个标签控件用于放置任务、进程和系统信息等三个页面,如图3。 think58.com

[版权所有:http://think58.com]

图3  标签控件
3.1.1 子对话框的显示
子对话框的显示与切换,是通过标签控件完成的。当用户点击标签控件上的每一项时,分别显示对应页面的相关信息。
要显示三个子对话框,需要添加三个对话框到工程中,并将Style属性设为Child,Board设为None,取消标题栏。再分别创建三个对话框的类CTask ,CProcess,CChart,并定义这三个类的变量:
CTask m_Task;              //任务
CProcess m_Process;        //进程
CChart m_Chart;            //图表
并定义一个图像列表变量用于存放标签图标:CImageList m_ImageList;
接下来就创建子窗口:
m_Task.Create(IDD_TASK,m_Tab.GetActiveWindow());
m_Process.Create(IDD_PROCESS,m_Tab.GetActiveWindow());
m_Chart.Create(IDD_CHART,m_Tab.GetActiveWindow());
当用户选择标签中的一项是,为了将对应的对话框在标签控件中显示出来,需要在OnShowWindow(BOOL bShow,UINT nStatus)中添加代码相关代码。这样便可将在个对话框分别显示于标签控件的每个页面中,但要实现选择标签的不同项显示不同页面还需在OnSelchangeMaintab(NMHDR* pNMHDR,LRESULT* pResult)和OnSelchangingMaintab(NMHDR* pNMHDR,LRESULT* pResult)两函数中添加显示代码。 [资料来源:www.THINK58.com]
void CPcsMgrDlg::OnSelchangeMaintab(NMHDR* pNMHDR, LRESULT* pResult)
{ switch(m_Tab.GetCurSel())
 {
 case 0:m_Task.ShowWindow(SW_SHOW);//任务页面被选中,则显示任务页面
  m_Task.CenterWindow();
  break;
 case 1:m_Process.ShowWindow(SW_SHOW); //任务页面被选中,则显示进程页面
  m_Process.CenterWindow();
  break;
 case 2:m_Chart.ShowWindow(SW_SHOW); //任务页面被选中,则显示系统信息页面
  m_Chart.CenterWindow();
  break;
 }
}
3.1.2 实现菜单
关机、注销、重起菜单命令是通过调用一个Windows API函数ExitWindowsEx()完成的。但在Windows 98和Windows 2000实现稍有不同。ExitWindowsEx()函数定义格式:
BOOL ExitWindowsEx(
UINT uFlags          //操作
DWORD dwReason       //原因
);
在Windows 98实现“注销/重启/关机”功能将直接调用ExitWindiwsEx函数:
ExitWindowsEx(EWX_LOGOFF,0);   // 注销
ExitWindowsEx(EWX_REBOOT,0);   // 重启

think58好,好think58

[来源:http://www.think58.com]


ExitWindowsEx(EWX_SHUTDOWN,0); // 关机
在Windows 2000实现“注销/重启/关机”功能须取得高级权限:
LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken,FALSE,&tkp,0,(PTOKEN_PRIVILEGES)NULL,0);
ExitWindowsEx(FFlag,0);
新建菜单直接调用系统运行对话框:
RUN RunFileDlg;
RunFileDlg = (RUN)GetProcAddress(hShell32, MAKEINTRESOURCE(61));
开机自动运行可在注册表的主键”HKEY_LOCAL_MACHINE”下的运行子键”Software\Microsoft\Windows\CurrentVersion\Run”下写入和删除一个键值的方法实现。
3.1.3 提升本程序权限
为了能够终止所有进程,需要提升本进程的权限:
1、先调用GetCurrentProcess函数取得当前进程的句柄;
2、然后调用OpenProcessToken打开当前进程的访问令牌;
3、接着调用LookupPrivilegeValue函数取得你想提升的权限的值;
4、最后调用AdjustTokenPrivileges函数给当前进程的访问令牌增加权限。
相关代码是在CPcsMgrApp类的InitInstance()函数中添加。
3.2 任务列表页面设计

内容来自think58 [资料来源:www.THINK58.com]


该类实现当前系统运行任务(有可见窗口的程序)的管理,如查看当前任务,添加新任务,结束任务,切换任务等。
3.2.1 显示任务信息
任务信息包括桌面窗口中可见程序的程序名、路径、运行状态等信息。在这里我们将在任务列表页面中添加一个列表控件,用于将任务信息显示出来,如图4。

copyright think58

[来源:http://www.think58.com]

[资料来源:http://THINK58.com]


图4  任务列表
要显示桌面窗口中的任务信息,首先要一个结构体类型用于存放任务的相关信息:
typedef struct
{
 CString strTaskName;  //窗口标题
 DWORD dwProcessID;    //进程ID
 DWORD dwThreadID;     //线程ID
 CString strRunState;  //运行状态
 DWORD dwWndHandle;    //窗口句柄
}TASK_IFNO,*PTASK_INFO;
获取窗口标题,使用API标准函数GetWindowText ():
char temp[MAX_PATH];
GetWindowText(hwnd,temp,sizeof(temp))
获取进程及线程ID:
TID=GetWindowThreadProcessId(hwnd,&PID);
确定运行状态:
if(SendMessageTimeout(hwnd,WM_SYSCOMMAND,NULL,NULL,SMTO_ABORTIFHUNG,1000,NULL))
  {
   strRunState = "正在运行";
  }
  else
  {
   strRunState = "没有响应";
  }
添加任务信息到数组:
 TASK_IFNO ti;
 ti.strTaskName = temp;
 ti.dwProcessID = PID;
 ti.dwThreadID = TID; think58.com [版权所有:http://think58.com]
 ti.dwWndHandle = (DWORD)hwnd;
 ti.strRunState = strRunState;
 pTaskThis->m_TaskInfoArray.Add(ti);
在任务列表显示每一行信息:
for(int i=0;i<newCount;i++)
 {
  TASK_IFNO ti;
  ti = m_TaskInfoArray.GetAt(i);
  if(m_task.GetItemText(i,0) != ti.strTaskName)
  {
   m_task.DeleteItem(i);
   m_task.InsertItem(i,ti.strTaskName,i);
   str.Format("%d",ti.dwProcessID);
   m_task.SetItemText(i,1,str);
   str.Format("%d",ti.dwThreadID);
   m_task.SetItemText(i,2,str);
   m_task.SetItemText(i,3,ti.strRunState);
  }
 }
3.2.2 结束任务
结束任务操作将调用SendMessageTimeout函数向要关闭的窗口发送关闭消息,如果没有响应则用TerminateProcess函数强行终止该窗口进程。
if(!SendMessageTimeout(hwnd,WM_SYSCOMMAND,SC_CLOSE,NULL,SMTO_BLOCK|SMTO_ABORTIFHUNG,1000,NULL))
{
 HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, ti.dwProcessID);//打开进程 copyright think58 [版权所有:http://think58.com]
 TerminateProcess(hProcess,1);//强制终止该窗口进程
 CloseHandle(hProcess);
}
3.2.3 切换任务
我们知道,Windows 9x/2000中SetForegroundWindow函数当用户正在操作其他窗口时是不能强制某个窗口为前景窗口的,而是激活窗口并调用FlashWindowEx函数来通知用户。但是很多实际情况要求将激活窗口的同时将创建这个窗口的线程置为前景状态。碰到这种情况我们可以使用USER32.DLL中的几个未公开API函数。
void SwitchToThisWindow (
 HWND hWnd,      //被激活的窗口句柄
 BOOL bRestore  //如果被极小化,则恢复窗口
);
typedef void (WINAPI *PROCSWITCHTOTHISWINDOW)(HWND,BOOL);
PROCSWITCHTOTHISWINDOW SwitchToThisWindow;
HMODULE hUser32 = GetModuleHandle("user32");
SwitchToThisWindow = (PROCSWITCHTOTHISWINDOW)
GetProcAddress(hUser32,"SwitchToThisWindow");
接下来只要用任何现存窗口的句柄调用这个函数即可,参数bRestore指定如果窗口极小化,是否恢复其原状态。
SwitchToThisWindow(hWnd,TRUE);
3.3 进程列表页面设计
该页面主要实现显示当前系统正在运行的所有进程并对其进程管理,如结束进程,显示进程模块信息,显示进程线程信息,保存进程信息在网页文件中等功能。同显示任务列表一样,我们将添加两个列表控件,分别显示所有进程信息和当前选择的进程的所以模块信息,如图5。

think58

[资料来源:THINK58.com]

[版权所有:http://think58.com]

图5  进程列表页面
3.3.1 显示进程信息
进程信息包括进程图标,进程名、进程ID、用户名、CPU使用率、内存使用率、优先级、线程数、父进程ID和进程路径等,如图6。 [资料来源:http://www.THINK58.com]