电子邮件脚本病毒在网络上泛滥成灾之后,作为脚本缺陷的始作俑者,WSH(Windows脚本主机)受到了广泛和强烈的抨击,不过,对应用程序开发人员而言,WSH仍然具备相当大的潜质和开发魅力。是的,脚本技术完全可能取代网络管理员对批处理文件的依赖,更时髦的脚本相信对那些“真正”的开发人员仍具相当的实用性。
比方说,你知道微软的Office套件如此流行的原因吗?其中之一就是所有的Office应用程序都包括了了简单的开发环境,稍有技术的用户都可以由此实现重复任务的自动化。VBA(VisualBasicforApplications)就为Office软件提供了这种环境,而且,如果你能承担微软要求的许可证费用,你还可以在你自己的应用程序中使用VBA。现在,我们再来看看WSH和WindowsScriptControl,它们是对VBA廉价而且相当有用的替代选择。为VisualBasic应用程序提供了自动的脚本化技术。
WindowsScriptControl把ActiveScriptingEngine封装在了非用户界面的ActiveX控件之内以方便VB编程的使用,而ActiveScriptingEngine正是WSH的核心。程序员可以利用该控件执行整个脚本或者脚本的片段,而这些脚本可以用WSH所支持的任何语言编写。也许你的计算机上已经安装了这种控件;它的名字是msscript.ocx,通常位于System32目录下。否则你可以从
WindowsScriptControl控件还包括了一些文档,但照我的经验看,这些文档有点不完整而且不太准确。掌握控件用法的最好方法就是具体应用它,通过具体应用了解其工作原理和用途。我自己就是这么做的,先创建了一个测试项目,用它来了解脚本控件的可能现象和用途,你可以从这里下载测试项目。这篇文章中会反复用到该测试项目。
为了运行用到脚本控件的脚本,你有以下若干选择:
Eval方法,它同VBAEval函数类似,从简单算术到包含嵌入脚本的命令或对象方法调用的复杂表达式都可以计算,而且会把结果返回给你的应用程序。
ExecuteStatement方法执行任何完整的脚本语句。
联合运用AddCode和Run方法可以装载并执行定制的脚本程序。这也是功能性最强大的方法,同时也是本文余下部分要讨论的方法。
ScriptingDemo简介
ScriptingDemo应用程序由一个窗体、两个文本框组成,窗体显示应用程序所在目录下的脚本文件列表,一个文本框获取脚本程序所需要的参数,另一个文本框显示执行脚本的输出结果。在应用程序启动的时候,它实例化一个定制集合对象colCustomers,通过它从SQLServer的Northwind目录的Customers数据表装载数据供我们的示例脚本操作数据。应用程序在运行时显示的主窗体如图A所示。
图A
运行时的ScriptingDemo主窗体
在选择了一个脚本之间之后,应用软件逐行读取脚本代码并通过AddCode方法把它加到脚本控件的环境内。单击RunScript按钮之后脚本控件就会执行所选文件同名(不带扩展名)的程序。
以ASimpleScript.vbs为例。它包含以下的子程序:
MsgBox"HellofromVBScript!"
EndSub
选择该文件,然后单击RunScript按钮即产生图B所示的输出结果。
图B
运行ASimpleScript.vbs之后的结果
对,我承认这个程序太简单了,但它确实说明你在运行脚本,除此以外,我们还需要深入控件内部探个究竟。
现在让我们更深入一步,看看隐藏在窗体Load事件(
ScriptControl1.AddObject"Output",oScriptOutput,True
PrivateSubForm_Load()
DimstrDirAsStringDirectorycontents
DimoCustomersAsNewcolCustomersplaycollection
DimoScriptOutputAsNewOutputOutputobjectforscript
Getalistofallvbsscriptfilesintheappdirectory
strDir=Dir(App.Path&"\*.vbs")
DoUntilstrDir=""
Me.List1.AddItemstrDir
strDir=Dir()
Loop
setupourscriptsplayenvironment.
SetoScriptOutput.OutputBox=Me.txtOutput
LoadDataacceptsaDSNname,auseridandapassword
oCustomers.LoadData"SQLServer","sa",""
Maketheseobjectsavailabletoscriptsrunwiththe
scriptcontrol.
ScriptControl1.AddObject"Output",oScriptOutput,True
EndSub->