SecureCrt脚本(三)二级对象之Screen详解
Crt自动化 测试 SecureCrt脚本 JS脚本
- 1、引言
- 2、Screen属性和方法
- 2.1、属性
- 2.1.1、CurrentColumn
- 2.1.2、CurrentRow
- 2.1.3、Columns
- 2.1.4、Rows
- 2.1.5、IgnoreEscape
- 2.1.6、MatchIndex
- 2.1.7、Synchronous
- 2.2、方法
- 2.2.1、Clear()
- 2.2.2、get()
- 2.2.3、get2()
- 2.2.4、IgnoreCase()
- 2.2.5、Send()
- 2.2.6、SendKeys()
- 2.2.7、SendSpecial()
- 2.2.8、WaitForCursor()
- 2.2.9、WaitForKey()
- 2.2.10、WaitForString()
- 2.2.11、WaitForStrings()
- 2.2.12、ReadString()
- 3、总结
1、引言
本节开始讲解Crt脚本中最常用,也是功能最强大的二级对象Screen的属性和方法,凡是需要和远程设备进行交互的部分都是需要使用Screen对象的属性或方法的,因此本节将是重点。
2、Screen属性和方法
属性 方法 CurrentColumn Clear CurrentRow Get Columns Get2 Rows IgnoreCase IgnoreEscape Send MatchIndex SendKeys Synchronous SendSpecial WaitForCursor WaitForKey WaitForString WaitForStrings ReadString
2.1、属性
2.1.1、CurrentColumn
解释返回当前光标处的列坐标,如下图所示的下面显示的数字"9"就是当前光标位于第9列。
语法crt.Screen.CurrentColumn
代码
- JS
1 # $language = "JScript" 2 # $interface = "1.0" 3 4 var curCol = crt.Screen.CurrentColumn; 5 crt.Dialog.MessageBox(curCol);
2.1.2、CurrentRow
解释返回当前光标处的行坐标,如下图所示的下面显示的数字"35"就是当前光标位于第35行。但这个功能有个问题就是当满屏输出后这个值一直表示最大值,等同于底下要讲的子属性四:Rows的值。
语法crt.Screen.CurrentRow
代码
- JS
1 # $language = "JScript" 2 # $interface = "1.0" 3 4 var curRow = crt.Screen.CurrentRow; 5 crt.Dialog.MessageBox(curRow);
2.1.3、Columns
解释返回当前屏幕的最大列宽。
语法crt.Screen.Columns
代码
- JS
1 # $language = "JScript" 2 # $interface = "1.0" 3 4 var cols = crt.Screen.Columns; 5 crt.Dialog.MessageBox(cols);
2.1.4、Rows
解释返回当前屏幕的最大行宽,这个行宽指的是可见区的,并不是指缓冲区的行宽
语法crt.Screen.Rows
代码
- JS
1 # $language = "JScript" 2 # $interface = "1.0" 3 4 var rows = crt.Screen.Rows; 5 crt.Dialog.MessageBox(rows);
2.1.5、IgnoreEscape
解释定义当使用WaitForString、WaitForStrings 和 ReadString这三个方法时是否获取Escape字符(也就是特殊控制字符,如"\n"),默认是会获取的。
语法crt.Screen.IgnoreEscape [ = True | False ]
参数:
true|false:当设置为true时不会获取特殊字符,为false时会获取,默认为false。
代码
- JS
1 # $language = "JScript" 2 # $interface = "1.0" 3 4 // 设置false,获取ctrl+c 5 crt.Screen.IgnoreEscape = false; 6 crt.Dialog.MessageBox(crt.Screen.ReadString("\03")); 7 8 // 设置true,不获取ctrl+c 9 crt.Screen.IgnoreEscape = true; 10 crt.Dialog.MessageBox(crt.Screen.ReadString("\03"));
2.1.6、MatchIndex
解释当使用WaitForStrings 和 ReadString这两个方法获取字符串时,会根据参数的位置获取返回值,而MatchIndex就是这个位置,从1开始计算,如果没有一个匹配到则返回0,可以根据下面的例子来看。
语法crt.Screen.MatchIndex
代码
- JS
1 # $language = "JScript" 2 # $interface = "1.0" 3 4 var outPut = crt.Screen.ReadString("error", "warning", "#", 10); 5 switch (crt.Screen.MatchIndex) { 6 case 0: 7 crt.Dialog.MessageBox("Timed out!") 8 break; 9 case 1: 10 crt.Dialog.MessageBox("Found 'error'") 11 break; 12 case 2: 13 crt.Dialog.MessageBox("Found 'warning'") 14 break; 15 case 3: 16 crt.Dialog.MessageBox("Found '#'") 17 break; 18 }
2.1.7、Synchronous
解释设置屏幕的同步属性,关于该属性需要谨慎对待,若设置为false,则在脚本中使用WaitForString、WaitForStrings或ReadString函数时可能存在丢失一部分数据的现象,而设置为true时不会,但是设置为true后可能会存在屏幕卡顿的情况,出现这两种现象的原因应该是和这几个函数以及打印字符到Screen的机制有关系,具体内部原因不明,就具体使用而言,如果是跑脚本的话最好还是不要设置为true,大量的卡顿看着就会蛋疼了,还可能会造成CRT卡死。
语法crt.Screen.Synchronous [ = True | False ]
参数:
true|false :默认为false
代码
- JS
1 # $language = "JScript" 2 # $interface = "1.0" 3 4 crt.screen.Synchronous = true; 5 crt.screen.Send("\r\n"); 6 crt.screen.ReadString("#"); 7 crt.screen.Send("\r\n"); 8 crt.screen.WaitForString("#"); 9 crt.screen.Send("\r\n"); 10 crt.screen.WaitForStrings("#",">");
2.2、方法
2.2.1、Clear()
解释清屏功能
效果类似下面这个屏幕:
语法crt.Screen.Clear()
代码
- JS
1 # $language = "JScript" 2 # $interface = "1.0" 3 4 crt.Screen.Send("\r\n"); 5 crt.Screen.Send("\r\n"); 6 crt.Screen.Send("\r\n"); 7 crt.Screen.Send("\r\n"); 8 crt.Screen.Clear();
2.2.2、get()
解释按照坐标取出一个矩形框内的屏幕上的字符(即从某行某列开始到其它行其它列),不包含字符串中的回车换行符,所以这个多用于获取无格式的光标处字符串或某小段特定区域字符串。
语法crt.Screen.Get(row1, col1, row2, col2)
代码
- JS
1 # $language = "JScript" 2 # $interface = "1.0" 3 4 var getScr = crt.Screen.Get(31,50,31,56); 5 crt.Dialog.MessageBox(getScr);
这段代码获取的是(31,50,31,56)这个矩阵内的字符串,即下图中红色框中所示的7483052。
2.2.3、get2()
解释按照坐标取出一个矩形框内的屏幕上的字符(即从某行某列开始到其它行其它列),包含字符串中的回车换行符,所以这个多用于获取大段带格式的字符串。
语法crt.Screen.Get2(row1, col1, row2, col2)
代码
- JS
1 # $language = "JScript" 2 # $interface = "1.0" 3 4 var getScr = crt.Screen.Get2(29,1,35,20); 5 crt.Dialog.MessageBox(getScr);
这段代码获取的是(29,1,35,20)这个矩阵内的所有带回车换行的字符串,即下图中红色框中文字。
2.2.4、IgnoreCase()
解释使用全局参数设置控制在使用WaitForString、WaitForStrings和ReadString这三个函数时是否对大小写敏感,默认为false指大小写敏感即大小写字符串都会检查,设置为true时则不会检测大小写。
语法crt.Screen.IgnoreCase
请注意,语法中并没有带(),根据语法来看,这个不像是方法,但是在CRT的使用说明中标注为了方法而不是属性,且在python的脚本中是当做方法使用的,因此这里先归类为方法,但是在JS脚本中是不带()使用的。
代码
- JS
1 # $language = "JScript" 2 # $interface = "1.0" 3 4 crt.Screen.IgnoreCase = true; 5 crt.Screen.Send("show memory\r\n"); 6 crt.Screen.WaitForString("more"); 7 crt.Screen.Send("\r\n"); 8 crt.Screen.WaitForStrings("more","#"); 9 crt.Screen.Send("\r\n"); 10 crt.Screen.ReadString("more","#");
2.2.5、Send()
解释向远端设备或者向屏幕(向屏幕发送的功能是CRT7.2以后版本才提供的)发送字符串。如语法中所表示的,string是待发送的字符串,这个字符串可以包含转码字符比如"\r","\n","\03"(ctrl+c),当向屏幕上发送字符串时需要指定第二个参数为true。有了向屏幕发送字符串的功能,我们就可以很方便的和用户进行交互了。可以打印出一些我们需要的报错信息之类的。
语法crt.Screen.Send(string, [, bSendToScreenOnly])
代码
- JS
1 # $language = "JScript" 2 # $interface = "1.0" 3 4 // 向远程设备发送英文命令"show memory" 5 crt.Screen.Send("show memory\r\n"); 6 7 // 向屏幕上发送字符串 8 crt.Screen.Send("hello,world!\r\n",true);可是运行了这段代码后很可能会发现,底下的向屏幕发送的字符串先打印到屏幕上了,效果如下,原因是Crt发送到屏幕的字符串可能先于远程设备返回的字符串,因此会先打印下面的。解决办法就是可以在发送屏幕的这一段前面加一个延时,这样就不会先打印下面的了。
2.2.6、SendKeys()
解释向当前窗口发送按键,包含组合按键,比如可以发送类似"CTRL+ALT+C"等这样的组合键,这样写即可:
crt.screen.sendkeys("^%c");这个功能需要语言本身支持,目前只有VBS和JS脚本可以使用,Python和Perl都不可以。
语法crt.Screen.SendKeys(string)
代码
- JS
1 # $language = "JScript" 2 # $interface = "1.0" 3 4 crt.Screen.Clear(); 5 crt.screen.sendkeys("mc~"); 6 crt.Sleep(2000); 7 crt.screen.sendkeys("{f1}"); 8 crt.Sleep(2000); 9 crt.screen.sendkeys("{esc}0"); 10 crt.Sleep(2000); 11 crt.screen.sendkeys("{esc}0"); 12 crt.Sleep(2000); 13 crt.screen.sendkeys("y");具体可以有哪些按键,参照下表,修改对应参数即可,可以根据需要自由组合:
Key(按键)
Argument(参数)
SHIFT
+
CTRL
^
ALT
%
BACKSPACE
{BACKSPACE}, {BS}, or {BKSP}
BREAK
{BREAK}
CAPS LOCK
{CAPSLOCK}
DEL or DELETE
{DELETE} or {DEL}
DOWN ARROW
{DOWN}
END
{END}
ENTER
{ENTER} or ~
ESC
{ESC}
HELP
{HELP}
HOME
{HOME}
INS or INSERT
{INSERT} or {INS}
LEFT ARROW
{LEFT}
NUM LOCK
{NUMLOCK}
PAGE DOWN
{PGDN}
PAGE UP
{PGUP}
PRINT SCREEN
{PRTSC}
RIGHT ARROW
{RIGHT}
SCROLL LOCK
{SCROLLLOCK}
TAB
{TAB}
UP ARROW
{UP}
F1, F2, ... F16
{F1}, {F2}, ... {F16}
0, 1, ... 9 on number pad
{NUM_0}, {NUM_1}, ... {NUM_9}
. on number pad
{NUM_.}
/ on number pad
{NUM_/}
* on number pad
{NUM_*}
- on number pad
{NUM_-}
+ on number pad
{NUM_+}
ENTER on number pad
{NUM_ENTER}
HOME on number pad
{NUM_HOME}
PAGE UP on number pad
{NUM_PGUP}
END on number pad
{NUM_END}
PAGE DOWN on number pad
{NUM_PGDN}
UP ARROW on number pad
{NUM_UP}
DOWN ARROW on number pad
{NUM_DOWN}
LEFT ARROW on number pad
{NUM_LEFT}
RIGHT ARROW on number pad
{NUM_RIGHT}
2.2.7、SendSpecial()
解释可以发送特殊控制码,这个控制码是Crt内置的功能,具体可以包含的有Menu、Telnet、VT functions功能列表中提供的所有功能,即下图中的这些,有兴趣可以调出new button后看到这些:
Menu Function:
Telnet:
VT functions:
语法
crt.Screen.SendSpecial(string)
代码
- JS
1 # $language = "JScript" 2 # $interface = "1.0" 3 // 以下是Crt文档中举的例子,具体还有什么我也没有试过,各位可以自己试试 4 crt.screen.SendSpecial("MENU_PASTE"); 5 crt.screen.SendSpecial("TN_BREAK"); 6 crt.screen.SendSpecial("VT_PF1");
2.2.8、WaitForCursor()
解释等待光标移动,当移动时返回值为true,当有超时时间参数且超时时返回false,否则会一直等待光标移动。利用这个功能可以用来判断一个命令的输出是否结束,只不过超时时间是以秒为单位的,对于脚本当中,这个时间还是略显久了。
语法crt.Screen.WaitForCursor([timeout])
代码
- JS
1 # $language = "JScript" 2 # $interface = "1.0" 3 4 // 每5秒内光标有移动时即发送一个命令 5 while (1) { 6 if ( crt.Screen.WaitForCursor(5) ) { 7 crt.Screen.Send("show version\r\n"); 8 } 9 }
2.2.9、WaitForKey()
解释检测有键盘按键时返回true,当有超时时间参数且超时时返回false,否则会一直等待按键。只可惜这个函数不知道输入的键是什么,否则就可以针对性的判断了,它只能检测到有输入而已。
语法crt.Screen.WaitForKey([timeout])
代码
- JS
1 # $language = "JScript" 2 # $interface = "1.0" 3 4 // 每5秒内有输入时发送一个命令 5 while (1) { 6 if ( crt.Screen.WaitForKey(5) ) { 7 crt.Screen.Send("show version\r\n"); 8 } 9 }
2.2.10、WaitForString()
解释一般用于发送命令后等待某字符串,这个字符串只要是屏幕上出现的即可,哪怕是粘贴上去的命令也会同样被检测到,也可以用于等待屏幕的输出打印,不需要先发送命令。不过一般我们使用它来检测的都是发送命令后出现的标识符。
语法crt.Screen.WaitForString(string,[timeout],[bCaseInsensitive])
参数:
1、string,必选参数,等待的字符串,可以是特殊字符比如:\r\n;
2、timeout,可选参数,超时时间,当检测不到对应字符串时会返回false,没有此参数时会一直等待;
3、bCaseInsensitive,可选参数,大小写不敏感,默认值是false,表示将检测字符串的大小写,当为true时不检测大小写。
代码
- JS
1 # $language = "JScript" 2 # $interface = "1.0" 3 4 // 发送命令,并在5秒内获取到对应的字符串后发送一条命令 5 crt.Screen.Send("\r\n"); 6 if ( crt.Screen.WaitForString("#",5) ) { 7 crt.Screen.Send("show version\r\n"); 8 } 9 crt.Screen.Send("\r\n"); 10 if ( crt.Screen.WaitForString(">",5) ) { 11 crt.Screen.Send("who\r\n"); 12 } 13 crt.Screen.Send("\r\n"); 14 if ( crt.Screen.WaitForString("$",5) ) { 15 crt.Screen.Send("ls -l\r\n"); 16 }
2.2.11、WaitForStrings()
解释和WaitForString是同样的功能,只不过可以等待多个字符串,如果有匹配到某个字符串,则返回值该字符串在这些字符串中的位置,位置值从1开始。若在超时时间内没有匹配到则返回false,没有超时时间时会一直等待。
语法crt.Screen.WaitForStrings([string1,string2..],[timeout],[bCaseInsensitive])
参数:
1、string,必选参数,等待的字符串,最少有一个,可以是特殊字符比如:\r\n;
2、timeout,可选参数,超时时间,当检测不到对应字符串时会返回false,没有此参数时会一直等待;
3、bCaseInsensitive,可选参数,大小写不敏感,默认值是false,表示将检测字符串的大小写,当为true时不检测大小写。
代码
- JS
1 # $language = "JScript" 2 # $interface = "1.0" 3 4 var outPut = crt.Screen.WaitForStrings("error", "warning", "#", 10); 5 var waitIndex = crt.Screen.MatchIndex 6 switch (waitIndex) { 7 case 0: 8 crt.Dialog.MessageBox("Timed out!") 9 break; 10 case 1: 11 crt.Dialog.MessageBox("Found 'error'") 12 break; 13 case 2: 14 crt.Dialog.MessageBox("Found 'warning'") 15 break; 16 case 3: 17 crt.Dialog.MessageBox("Found '#'") 18 break; 19 }上面也用到了crt.Screen.MatchIndex功能,具体可以见上面的2.1.6节。
2.2.12、ReadString()
解释这个功能和上面的WaitForStrings函数有些类似,都是等待某几个字符串出现,不过不同的是,ReadString函数还会读取字符串之前的所有出现的字符,这个功能可以很方便的用于发送一个命令后获取这个命令的输出结果,不过这个函数也不是特别稳定,因为很可能存在命令的输出结果很快,而屏幕又没有捕捉到时,要么会由于超时而返回false,要么会一直等待,最终返回的都是空值,因此完全依靠该函数获取命令的输出的话并不是很把稳(如果程序对于稳定性要求很高的话,那么最好还是不要依赖这个函数。)
语法crt.Screen.ReadString([string1,string2..],[timeout],[bCaseInsensitive])
参数:
1、string,必选参数,等待的字符串,最少有一个,可以是特殊字符比如:\r\n;
2、timeout,可选参数,超时时间,当检测不到对应字符串时会返回false,没有此参数时会一直等待;
3、bCaseInsensitive,可选参数,大小写不敏感,默认值是false,表示将检测字符串的大小写,当为true时不检测大小写。
代码
- JS
1 # $language = "JScript" 2 # $interface = "1.0" 3 4 // 发送命令并根据提示符获取命令的输出。 5 crt.Screen.Send("show version\r\n"); 6 crt.Screen.WaitForString("show version",2); 7 var outPut = crt.Screen.ReadString("error", "warning", "#", 10); 8 var waitIndex = crt.Screen.MatchIndex 9 switch (waitIndex) { 10 case 0: 11 crt.Dialog.MessageBox("Timed out!") 12 break; 13 case 1: 14 crt.Dialog.MessageBox("Found 'error'") 15 break; 16 case 2: 17 crt.Dialog.MessageBox("Found 'warning'") 18 break; 19 case 3: 20 crt.Dialog.MessageBox("命令的输出时:"+outPut); 21 break; 22 }在这个举例中的第6行可以看到还使用了WaitForString,为什么要使用这个,有两个方面原因,一是确定命令已经被发送到了远端设备,二是确保命令的输出结果中没有改命令,而仅仅是该命令的输出结果。
3、总结
以上就是Screen这个二级属性的所有子属性和子方法了,这里面的功能都是CRT系列中最最重要的功能,也是最常用的功能,大家可以平时在写脚本时多琢磨这些函数的用法和奇妙之处。