好文档就是一把金锄头!
欢迎来到金锄头文库![会员中心]
电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

附录A 控制台程序.doc

8页
  • 卖家[上传人]:工****
  • 文档编号:547588352
  • 上传时间:2023-07-15
  • 文档格式:DOC
  • 文档大小:192.51KB
  • / 8 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • ·7·附录A 控制台程序附录A 控制台程序在Windows操作系统中运行一个应用程序后,我们经常会看到两种界面,一种是标准的窗口界面,窗口界面的程序架构在第4章中已经有了详细的介绍;另一种是类似于MS-DOS程序的文本界面,如常用的Ping、Xcopy等命令使用的都是这种界面,这种界面就叫做控制台(Console),由于控制台在Windows系统中还是以一个文本窗口的方式出现的,所以一般将这个窗口称为控制台窗口从表面看,32位的控制台程序和16位的MS-DOS应用程序在外观和表现上都是很相似的,比如它们都是在一个黑洞洞的文本窗口中显示文本,都支持命令行下的重定向操作,读取键盘的方式也是一样的但是,在这个表象下面,两者却是完完全全不同的,DOS应用程序是16位的实模式程序,而Windows下的控制台程序却是不折不扣的32位保护模式程序,它可以使用Win32 API函数,文件头中同样有导入表和导出表,可以在程序中建立多个线程执行总之,控制台程序是长着“DOS程序面孔”的Win32程序,可以使用Win32编程中的所有特征进一步来说,如果一定要让控制台程序有一个窗口的话,也可以在其中使用CreateWindow函数来创建一个窗口,这样控制台程序可以在使用终端界面输入输出的同时使用窗口上的菜单来操作(但估计没有人会做这样的事情)。

      控制台程序最主要的用途是用于网络的远程维护进行远程维护时一般使用Telnet等工具登录到远程主机并在上面执行命令,如果执行的是图形界面的程序,这个界面是无法远程操作的,所以我们可以发现Windows中用于网络的命令大多数是控制台界面的,如Ping,Netstat,Tracert,Arp,Route,Ipconfig和Finger等,与此相比,很难想像类似于Office这样的软件会用在远程操作中作为对第4章中窗口模式的补充,本节中将简单介绍控制台程序和窗口程序的区别,以及控制台程序的写法A.1 控制台程序和窗口程序的区别除了和界面相关的代码有所不同外,控制台程序和窗口程序的区别还在于链接的时候指定参数的不同,读者一定还记得LINK程序有个subsystem参数,当这个参数指定为Windows的时候,链接器生成的是窗口程序,本书中绝大部分以窗口为界面的例子程序中,LINK语句是这样写的: Link /subsystem:windows Test.obj Test.res将subsystem参数改为console的时候,LINK程序产生的就是控制台文件: Link /subsystem:console Test.obj Test.res两种参数生成的可执行文件的不同表现在文件头中,可执行文件(PE文件)的文件头中有个IMAGE_OPTIONAL_HEADER32结构,结构中的Subsystem字段就记录了文件类型的不同,读者可以在第17章的17.1.3小节中看到对文件头的详细分析。

      运行文件时,操作系统会检查文件头中的Subsystem参数,如果发现参数的类型是窗口文件,那么将文件以正常的方式运行;如果发现参数的类型是控制台文件,那么操作系统将为程序创建一个控制台窗口(即类似于DOS窗口的这个文本窗口),然后运行文件另外,当一个控制台程序是被另一个控制台程序作为子进程运行的时候,系统不会为它创建新的控制台窗口,而是将父进程的窗口指定给它,所以在“我的电脑”中双击运行一个控制台程序的时候,会出现一个新的控制台窗口,而在“命令提示符”窗口中用命令行参数运行一个控制台程序的时候,程序会直接使用“命令提示符”的窗口我们可以用几个简单的实验来验证这一点首先打开“命令提示符”,进入第4章例子程序的目录Chapter04\FirstWindow(这是一个普通的窗口程序而不是控制台程序),在命令行下输入FirstWindow来运行程序,程序运行后窗口出现了,但是不必等到窗口关闭,“命令提示符”就会直接回到等待输入命令的状态,也就是说,普通的窗口程序并不会占用父进程的控制台窗口现在修改Chapter04\FirstWindow目录中的makefile文件,将LINK命令的参数改成/subsystem:console,然后用nmake /a重新编译,这样程序的代码没有任何变化,仅仅是它的文件类型变成了控制台程序而已。

      重复上面的步骤,在命令行下运行FirstWindow程序,可以看到,程序运行后窗口出现了,但是“命令提示符”处于等待状态,只有关闭窗口FirstWindow程序,“命令提示符”中才会回到等待输入的状态,这说明控制台程序的父进程如果也是控制台程序的时候,程序将继承父进程的控制台窗口现在在“程序管理器”中通过双击FirstWindow.exe文件来运行,一个正常窗口出现的同时也出现了一个新的文本窗口,但是源代码中并没有创建过这个窗口呀?原来这个窗口就是操作系统自动“搭配”给程序的控制台窗口,关闭窗口退出程序后,控制台窗口也同时消失这说明了当父进程不是控制台程序的时候,操作系统会自动为控制台程序创建一个控制台窗口所以,除了操作系统会在上述方面对控制台窗口的创建或继承进行一些准备工作外,控制台程序和窗口程序在其它方面并没有什么不同,控制台程序中仍然可以有消息循环,可以创建窗口,也可以做窗口程序能做的任何事情A.2 书写控制台程序现在用一个例子来说明如何在控制台程序中进行输入及输出,例子程序的源代码位于Appendix A\EchoLine目录中,程序运行后,会等待用户输入一些字符,当用户敲回车键后,程序读入输入的行并以蓝色将输入的内容重新显示出来,然后等待用户输入新的一行并循环往复。

      如果用户按下Ctrl+C,程序将退出执行程序的界面如图A.1所示,读者可以注意到,例子程序的控制台窗口的标题是“EchoLine例子”如果在“命令行提示符”中运行这个程序,窗口的标题也会从“命令提示符”变成“EchoLine例子”,等程序退出以后,标题会恢复到“命令提示符”图A.1 EchoLine例子程序的界面例子程序的源代码如下: .386 .model flat, stdcall option casemap :none;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; Include;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>include windows.incinclude kernel32.incincludelib kernel32.lib;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; 数据段;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> .data?hStdIn dd ? ;控制台输入句柄hStdOut dd ? ;控制台输出句柄szBuffer db 1024 dup (?)dwBytesRead dd ?dwBytesWrite dd ? .constszTitle db 'EchoLine例子',0;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; 代码段;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> .code;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; 控制台 Ctrl-C 捕获例程;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>_CtrlHandler proc _dwCtrlType pushad mov eax,_dwCtrlType .if eax == CTRL_C_EVENT || eax == CTRL_BREAK_EVENT invoke CloseHandle,hStdIn .endif popad mov eax,TRUE ret_CtrlHandler endp;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>start:;********************************************************************; 获取控制台句柄、设置句柄属性;******************************************************************** invoke GetStdHandle,STD_INPUT_HANDLE mov hStdIn,eax invoke GetStdHandle,STD_OUTPUT_HANDLE mov hStdOut,eax invoke SetConsoleMode,hStdIn,ENABLE_LINE_INPUT or \ ENABLE_ECHO_INPUT or ENABLE_PROCESSED_INPUT invoke SetConsoleCtrlHandler,addr _CtrlHandler,TRUE invoke SetConsoleTitle,addr szTitle;********************************************************************; 循环读取控制台输入并显示;******************************************************************** .while TRUE invoke SetConsoleTextAttribute,hStdOut,FOREGROUND_RED\ or FOREGROUND_GREEN or FOREGROUND_BLUE invoke ReadConsole,hStdIn,addr szBuffer,\ sizeof szBuffer,addr dwBytesRead,NULL .break .if ! eax invoke SetConsoleTextAttribute,hStdOut,\ FOREGROUND_BLUE or FOREGROUND_INTENSITY invoke WriteConsole,hStdOut,addr szBuffer,\ dwBytesRead,addr dwBytesWrite,NULL .endw invoke ExitProcess,NULL;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> end start控制台程序输入输出的表现和DOS程序类似,它可以从标准输入设备进行输入,也可以输出到标准输出设备或者标准错误输出设备,所以,控。

      点击阅读更多内容
      关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
      手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
      ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.