操作系统实验指导书(5)

2019-01-04 23:12

2.2 Windows 2000编程

2.2.2 背景知识

Windows 2000可以识别的应用程序包括控制台应用程序、GUI应用程序和服务应用程序。控制台应用程序可以创建GUI,GUI应用程序可以作为服务来运行,服务也可以向标准的输出流写入数据。不同类型应用程序问的惟一重要区别是其启动方法。

Windows 2000是以NT技术构建的,它提供了创建控制台应用程序的能力,使用户可以利用标准的C++工具,如iostream库中的cout和cin对象,来创建小型应用程序。当系统运行时,Windows 2000的服务通常要向系统用户提供所需功能。

服务应用程序类型需要ServiceMail()函数,由服务控制管理器(SCM)加以调用。SCM是操作系统的集成部分,负责响应系统启动以开始服务、指导用户控制或从另一个服务中来的请求。其本身负责使应用程序的行为像一个服务。通常,服务登录到特殊的LocalSystem账号下,此账号具有与开发人员创建的服务不同的权限。

当C++编译器创建可执行程序时,编译器将源代码编译成OBJ文件,然后将其与标准库相链接。产生的EXE文件是装载器指令、机器指令和应用程序的数据的集合。装载器指令告诉系统从哪里装载机器代码。另一个装载器指令告诉系统从哪里开始执行进程的主线程。在进行某些设置后,进入开发者提供的main()、ServiceMain()或WinMain()函数的低级入口点。机器代码中包括控制逻辑,它所做的事包括跳转到Windows API函数,进行计算或向磁盘写入数据等。

Windows允许开发人员将大型应用程序分为较小的、互相有关系的服务模块,即动态链接库(DLL)代码块,在其中包含应用程序所使用的机器代码和应用程序的数据。

2.2.2 实验目的

通过对Windows 2000编程,进一步熟悉操作系统的基本概念,较好地理解Windows 2000的结构。

2.2.3 工具/准备工作

在开始本实验之前.请回顾教科书的相关内容。 您需要做以下准备;

? ?

一台运行Windows 2000 Professional操作系统的计算机 计算机中需安装Visual C++ 6.0专业版或企业版

2.2.4 实验内容与步骤

(1)控制台程序

先来创建一个名为―Hello,world‖的应用程序。 步骤1:登录进入Windows 2000 Professional;

步骤2:在―开始‖菜单中单击―程序‖、―附件‖、―记事本‖,的程序输入记事本中,并把

代码保存为Hello.cpp。

程序2-1 个简单的Windows 2000控制台应用程序 // hello项目 # include

18

void main() {

std::cout << \

}

步骤3:在―开始‖菜单中单击―程序‖、―附件‖、―命令提示符‖,进入Windows―命令提示

符‖窗口,并利用简单的标准命令行 C:\\> CL Hello.cpp

来创建可执行的Hello.exe。

操作能否正常进行?如果不行,原因是什么?

步骤4:运行Hello.exe程序,产生用户键入的一行文字。

运行结果(如果运行不成功,原因是什么?):

(2)GUI应用程序

在下面的实验中,C++编译器创建一个GUI应用程序,WinMain()方法.这是GUI类型

的应用程序的标准入口点。

步骤1:在―开始‖菜单中单击―程序‖、―附件‖、―记事本‖的程序键入记事本中,并把代

码保存为2-2.cpp。 程序2-2:Windows 2000的GUI应用程序 // msgbox项目

# include //标准的include //告诉连接器与包括MessageBox API函数的user32库进行连接 #pragma comment(lib,\

// 这是一个可以弹出信息框然后退出的简单的应用程序

int APIENTRY WinMain(HINSTANCE /* hInstance*/, {

::MessageBox(

NULL, //没有父窗口 \ //消息框中的文本 \ //消息框标题

MB_OK); //其中只有一个OK按钮

19

HINSTANCE /* hPrevInstance*/, LPSTR /* lpCmdLine */, int /* nCmdShow */ )

//返回0以便通知系统不进入消息循环 return(0); }

也可以利用任何其他文本编辑器键入程序代码,如果这样,例如使用word来键入和编辑程序,应该注意什么问题?

步骤2:在―命令提示符‖窗口运行CL.exe,产生3-2.exe文件: C:\\>CL 2-2.cpp

在程序2-2的GUI应用程序中,首先需要window.h头文件,以便获得传送给WinMain()和MesssageBox() API函数的数据类型定义。

接着的pragma指令指示编译器/连接器找到User32.LIB库文件并将其与产生的EXE文件连接起来。这样就可以运行简单的命令行命令CL MsgBox.CPP来创建这一应用程序,如果没有pragma指令,则MessageBox() API函数就成为未定义的了。这一指令是VisuaI Studio C++编译器特有的。

接下来是Winmain()方法。其中有四个由实际的低级入口点传递来的参数,hInstance参数用来装入与代码相连的图标或位图一类的资源,无论何时,都可用GetModuleHandle() API函数将这些资源提取出来。系统利用实例句柄来指明代码和初始的数据装在内存的何处。句柄的数值实际上是EXE文件映像的基地址,通常为0x00400000。下一个参数hPrevInstance是为向后兼容而设的,现在系统将其设为NULL。应用程序的命令行(不包括程序的名称)是lpCmdLine参数。另外,系统利用nCmdShow参数告诉应用程序如何显示它的主窗口(选项包括最小化、最大化和正常)。 最后,程序调用MessageBox() API函数并退出。如果在进入消息循环之前就结束运行的话,最后必须返回0。

运行结果(试将其中的信息与程序2-1程序的运行结果进行比较):

(3)进程对象

操作系统将当前运行的应用程序看作是进程对象。利用系统提供的惟一的称为句柄

(HANDLE)的号码,就可与进程对象交互,这一号码只对当前进程有效。

本实验表示了一个简单的进程句柄的应用。在系统中运行的任何进程都可调用GetCurrentProcess() API函数,此函数可返回标识进程本身的句柄。然后就可在Windows需要该进程的有关情况时,利用这一句柄来提供。

步骤1:将程序2-3键入记事本中,并把代码保存为2-3.cpp。

程序2-3 获得和使用进程的句柄 // prohandle项目 # include

20

# include

// 确定自己的优先权的简单应用程序 void main() {

// 从当前进程中提取句柄

HANDLE hProcess This =:: GetCurrentProcess(); // 请求内核提供该进程所属的优先权类

DWORD dwPriority=:: GetPriorityClass(hProcess This); // 发出消息,为用户描述该类 std:: cout<<‖Current process priority:‖; switch(dwPriority) {

case HIGH_PRIORITY_CLASS: std::cout<<‖High‖; break;

case NORMAL_PRIORITY_CLASS: std::cout<<‖Normal‖; break;

case IDLE_PRIORITY_CLASS: std::cout<<‖Idle‖; break;

case REALTIME_PRIORITY_CLASS: std::cout<<‖Realtime‖; break; default:

std::cout<<‖‖; break; }

std::cout<

程序2-3中列出的是一种获得进程句柄的方法。对于进程句柄可进行惟一有用的操作是在API调用时,将其作为参数传送给系统,正如程序3-3中对GetPriorityClass() API函数的调用那样。在这种情况下,系统向进程对象内―窥视‖,以决定其优先级,然后将此优先级返回给应用程序。

OpenProcess()和CreateProess() API函数也可以用于提取进程句柄。前者提取的是已经存在的进程的句柄,而后者创建一个新进程,并将其句柄提供出来。 步骤2:在―命令提示符‖窗口运行CL.exe产生2-3.exe文件

C:\\>CL 2-3.cpp

21

运行结果:

步骤3:将程序2-4的程序记入记事本中,并把代码保存为2-4.cpp。

程序2-4显示如何找出系统中正在运行的所有进程,如何利用OpenProcess() API函数来获得每一个访问进程的进一步信息。 程序3-4 利用句柄查出进程的详细信息 // proclist项目 # include # include # include

// 当在用户模式及内核模式下都提供所耗时间时、在内核模式下进行所耗时间的64位计算的帮助方法 DWORD GetKernelModePercentage(const FILETIME &ftKernel,

const FILETIME &ftUser)

{

// 将FILETIME结构转化为64位整数

ULONGLONG qwKernel=(((ULONGLONG) ftKernel.dwHighDateTime)<<32)+ ftKernel.dwLowDateTime;

ULONGLONG qwUser=(((ULONGLONG) ftUser.dwHighDateTime)<<32)+ ftUser.dwLowDateTime;

// 将消耗时间相加,然后计算消耗在内核模式下的时间百分比 ULONGLONG qwTotal= qwKernel+ qwUser;

DWORD dwPct=(DWORD)(((ULONGLONG) 100*qwKernel)/qwTotal); return (dwPct); }

// 以下是将当前运行进程名和消耗在内核模式下的时间百分数都显示出来的应用程序 void main() {

// 对当前系统中运行的进行拍取―快照‖

HANDEL hSnapshot=:: CreateToolhelp32Snapshot(

TH32CS-SNAPPROCESS, // 提取当前进程

0); // 如果是当前进程,就将其忽略 // 初始化进程入口 PROCESSENTRY32 pe;

22


操作系统实验指导书(5).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:《机械制造技术基础》教案-2010

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: