WshShell提供对本地 Windows 外壳程序的访问。可以通过WshShell 对象模拟键盘,向激活窗口发送键值实现选择,弹出定时提示框,注册表的读写,程序的启动,系统等待,添加Event Log,创建快捷方式等与windows联系比较紧密的操作。这些操作如果使用QTP来操作可能不是最佳方案,甚至可能QTP根本无法完成,此时就可以用WSH对象来帮助解决此类问题。
首先了解下跟对象Wscript:Windows Script Host Object model
简单的说Wscript就是一个windows脚本宿主对象模型,而Wscript是一个基于windows脚本宿主对象的根对象。利用它可以创建两种COM对象:WshShell跟WshNetWork。
注释:COM对象:The Component Object Model 组件对象模型
COM组件是遵循COM规范编写、以Win32动态链接库(DLL)或可执行文件(EXE)形式发布的可执行二进制代码,能够满足对组件架构的所有需求。
其中WshNetWork对象主要用于访问局域网环境下的资源共享,自动化测试过程中用到较少,我也没有深入研究过,不多做阐述。本文主要讲一些自动化测试中常用的WSH应用。
先举个例子,看似很简单的例子,我还是遇到了些麻烦,就以下这段代码我直接在notepad里手写的,但是运行居然报了错。错误如图。
Set wsh = CreateObject("Wscript.shell")
wsh.Run "notepad"
Set wsh = Nothing
然后我在程序第一行加了一句Dim wsh,再运行就通过了。大家都知道vbs并不强制定义变量,查了资料才知道wsh是Wscript的内置变量,正确的名称是WSH,vb中不区分大小写。
所以我们可以避免使用wsh这个变量名。
1. AppActivate方法
窗口激活经常在自动化测试中需要用到,特别是需要等待测试对象出现后再做的激活,往往需要一定的等待时间。如果hard code进去一个固定的等待时间,固然可以,但是如果考虑到测试机本身的不稳定性,以及一旦脚本多,如果这个等待时间设置的过长,必然造成时间上的浪费,如果设置了过短,则会造成测试结果的不准确。所以此时使用循环判断窗口是否激活成功就成了关键,WshShell对象提供了一个非常有用的功能。
语法:
Object.AppActivate title
参数:
Title为需要激活窗口的title属性值,也就是标题或者是ProcessID
返回值:
返回一个布尔值,如果当前窗口激活则返回True,反之返回False
举个例子来说明窗口激活的必要性,很简单的打开一个notepad并输入“sunyu”
Set swsh = CreateObject("Wscript.Shell")
swsh.Run "notepad"
While Not swsh.AppActivate("无标题 - 记事本"):Wend
swsh.SendKeys "sunyu"
Set swsh = Nothing
如果你将While Not swsh.AppActivate("无标题 - 记事本"):Wend 这行代码注释掉的话,就很可能无法把“sunyu“输入到notepad里去了。
再举个经典的例子,可以让大家更加清楚的看到这行代码的重要性。
程序一:
Set swsh = CreateObject("Wscript.Shell")
swsh.Run "notepad"
msgbox "sunyu"
Set swsh = Nothing
程序二:
Set swsh = CreateObject("Wscript.Shell")
swsh.Run "notepad"
While Not swsh.AppActivate("无标题 - 记事本"):Wend
msgbox "sunyu"
Set swsh = Nothing
程序一的运行结果:
程序二的运行结果:
一目了然,无需再多做解释了吧。
2. SendKeys方法的用法
SendKeys恐怕是WSH对象最常用的方法了,主要用在对象无法识别时,又要在此对象中输入字符串,即可用该方法。又或者需要用到快捷键时,同样可以用该方法。
语法:
Object.Sendkeys(string)
参数:
String表示需要发送的字符串,以及一些特殊的键盘符
常用的特殊键:
Shift---------WshShell.SendKeys "+"
Ctrl---------WshShell.SendKeys "^"
Alt---------WshShell.SendKeys "%"
Space---------WshShell.SendKeys " "
Enter---------WshShell.SendKeys "{ENTER}"
←---------WshShell.SendKeys "{RIGHT}"
↑---------WshShell.SendKeys "{UP}"
F1---------WshShell.SendKeys "{F1}"
我只列举了一小部分,具体到用的时候有不清楚的可以在网上查到。
下面这个程序就是调用的任务管理器
Set swsh = CreateObject("Wscript.Shell")
swsh.SendKeys "^+{ESC}"
Set swsh = Nothing
3. 注册表的读写
在我之前的文章中经常会出现对注册表的读写,如果注册表的读写也能写进脚本里,那么我们的很多设置都会变得方便并且更加易于维护。WSH提供了方法对注册表进行增加,删除,读取等这些操作。
写注册表
语法:
Object.RegWrite(strName,anyValue [,strType])
参数:
strName: 键的路径名
anyValue:键值
strType:可选,键的类型,默认为“REG_SZ“
举个例子,在自启动项中增加一项:
Set swsh = CreateObject("Wscript.Shell")
regPath = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\"
swsh.RegWrite regPath + "sunyu","d:\1.vbs"
Set swsh = Nothing
执行后结果如下图:
这样做对于间断性重启的自动化测试无疑来说是一个非常有用的方法。
读取注册表
语法:
Object.RegRead(strName)
参数:
strName:键的路径名
返回值:键的Value值
实例:
Set swsh = CreateObject("Wscript.Shell")
regPath = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run"
MsgBox swsh.RegRead(regPath+"\sunyu")
Set swsh = Nothing
结果如图:
下面的这段代码是遍历了注册表里的项,我把值打印出来了。
const HKEY_CURRENT_USER = &H80000001
Set objReg=GetObject("Winmgmts:\root\default:StdRegProv")
strKeyPath = "Software\Microsoft\Windows\CurrentVersion"
objReg.EnumKey HKEY_CURRENT_USER, strKeyPath, arrSubKeys
print "Subkeys under " _
& "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion"
For Each subkey In arrSubKeys
print subkey
Next
注释:这是我在网上找到的英文资料,我是根据这个写的上面那段代码,有兴趣的可以看看。
Syntax
uint32 EnumKey(
[in, optional] uint32 hDefKey = HKEY_LOCAL_MACHINE,
[in] string sSubKeyName,
[out] string sNames[]
);
Parameters
hDefKey [in, optional]
A registry tree, also known as a hive, that contains the sSubKeyName path. The default value is HKEY_LOCAL_MACHINE.
Note that HKEY_DYN_DATA is a valid tree for Windows 95 and Windows 98 computers only.
The following trees are defined in Winreg.h.
HKEY_CLASSES_ROOT (2147483648 (0x80000000))
HKEY_CURRENT_USER (2147483649 (0x80000001))
HKEY_LOCAL_MACHINE (2147483650 (0x80000002))
HKEY_USERS (2147483651 (0x80000003))
HKEY_CURRENT_CONFIG (2147483653 (0x80000005))
HKEY_DYN_DATA (2147483654 (0x80000006))
删除注册表
语法:
Object.RegDelete(strName)
参数:
strName:键的路径名
实例:
Set swsh = CreateObject("Wscript.Shell")
regPath = "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run"
swsh.RegDelete(regPath+"\sunyu")
Set swsh = Nothing
程序很简单,关键是删除前该键路径是否存在,不存在的话会报错。
4. 获取当前路径
在自动化测试中获取当前路径是很重要的,不管对于脚本移植,还是在自动化测试框架中都有着非常重要的意义。当然利用FSO对象也是可以获取到相对路径的,我在后续的文章里会介绍。这里先举个很简单的例子
我在vbsEdit的目录下面加了一个vbs文件,就是打印一句话,我通过CurrentDirectory
去获取到当前的路径,然后直接运行我的vbs脚本,代码跟结果如下图。
总结:
WshShell是自动化测试中非常常用的技术,它提供的方法极大低简化了自动化测试过程中的一些操作,除了这些常用的方法外,它还存在很多其他方法,更多的方法可以参考微软提供的MSDN在线帮助。