MSScriptControl详解(可实现在C#等语言中调用JAVASCRIPT代码)
ScriptControl接口
属性名称
|
类型
|
备注
|
AllowUI
|
BOOL
|
检测是否允许运行用户的接口元素。如果为False,则诸如消息框之类的界面元素不可见。
|
CodeObject
|
Object
|
脚本暴露给宿主调用的对象。只读。
|
Modules
|
Modules
|
宿主提供给脚本的组件库模块。只读。(COM组件通常都是以对象收集的形式向用户提供可以留给用户二次开发的对象集合,每一个收集即一个Modules)
|
Language
|
String
|
设置或获取脚本引擎解释的语言,例如:VBScript、JScript。
|
Name
|
String
|
脚本引擎的名称。只读。
|
Procedures
|
Procedures
|
返回模块中定义的过程的集合
|
SitehWnd
|
HWND
|
在脚本中显示UI的父窗口句柄
|
State
|
Enum
|
设置或返回控件的状态,如果为0,控件只执行语句但不转发事件,为1则为加入的本控件接受的对象转发事件。
|
Timeout
|
Long
|
控件的执行脚本的超时值,-1表示不超时
|
UseSafeSubset
|
BOOL
|
设置或返回宿主程序是否关心安全。宿主程序的安全级别可以从此属性设置
|
Error
|
Error
|
错误对象,发生错误时,此属性返回一个错误对象
|
方法名称
|
参数
|
功能
|
AddCode
|
Code As String
|
往脚本引擎中加入要执行的脚本
|
AddObject
|
Name As String, Object As Object, [AddMembers As Boolean = False]
|
往脚本引擎加入一个对象,以便在脚本中可以使用该对象提供的方法等。
|
Eval
|
Expression As String
|
表达式求值
|
ExecuteStatement
|
Statement As String
|
解释并执行脚本语句
|
Reset
|
|
丢弃所有的对象和代码,将State属性置0。
|
Run
|
ProcedureName As String, ParamArray Parameters() As Variant
|
运行一个指定的过程
|
事件名称
|
功能
|
Error
|
有错误发生时激发该事件
|
TimeOut
|
执行过程超时时发生
|
一般使用方法
1、在程序中加入ScriptControl
2、定义一个ScriptControl的实例
3、调用AddCode等方法向脚本引擎中加入要执行的脚本。
4、调用Run执行要执行的脚本函数。
宿主与脚本的通讯
1、 宿主调用脚本:这个过程比较简单,只要调用Run就可以将参数传递到脚本。
2、 脚本调用宿主:在初始化过程中调用AddObject接口,将宿主的一个或多个对象暴露给脚本,这时就可以在脚本中调用宿主对象的方法。在VC++中这个对象不是普通的C++类,它必须支持自动化,在脚本中也只能调用对象中自动化接口(在VB中这个个程相对比较简单)。
脚本调试
任何人写的代码都不可能一次就很完美,但是脚本由于执行的位置特殊,调试方法也不一样。首先下载一个脚本调试器(我用的是Microsoft Script Debugger, 在MS网站有下载,另据说其它的如VJ++也可以),安装以后在菜单上没有启动菜单。
调试器的启动
在一般的高级语言中都可以方便的设置断点,但是在启动脚本调试器以前如何开始调试呢?在IE中脚本出错会自动提示是否调试,还可以在脚本中加入中断代码(VBScript: Stop JavaScript: debugger),但是在ScriptControl还需要修改一下注册表才可以,你需要将HKEY_CURRENT_USER\Software\Microsoft\Windows Script\Settings下的JITDebug的值改为1(默认为0)
以下是C#引用的完整代码示例:
using System; using MSScriptControl; using System.Text; namespace ZZ { /// <summary> /// 脚本类型 /// </summary> public enum ScriptLanguage { /// <summary> /// JScript脚本语言 /// </summary> JScript, /// <summary> /// VBscript脚本语言 /// </summary> VBscript, /// <summary> /// javascript脚本语言 /// </summary> javascript } /// <summary> /// 脚本运行错误代理 /// </summary> public delegate void RunErrorHandler(); /// <summary> /// 脚本运行超时代理 /// </summary> public delegate void RunTimeoutHandler(); /// <summary> /// ScriptEngine类 /// </summary> public class ScriptEngine { private ScriptControl msc; //定义脚本运行错误事件 public event RunErrorHandler RunError; //定义脚本运行超时事件 public event RunTimeoutHandler RunTimeout; /// <summary> ///构造函数 /// </summary> public ScriptEngine():this(ScriptLanguage.VBscript) { } /// <summary> /// 构造函数 /// </summary> /// <param name="language">脚本类型</param> public ScriptEngine(ScriptLanguage language) { this.msc = new ScriptControlClass(); this.msc.UseSafeSubset = true; this.msc.Language = language.ToString(); ((DScriptControlSource_Event)this.msc).Error += new DScriptControlSource_ErrorEventHandler(ScriptEngine_Error); ((DScriptControlSource_Event)this.msc).Timeout += new DScriptControlSource_TimeoutEventHandler(ScriptEngine_Timeout); } /// <summary> /// 运行Eval方法 /// </summary> /// <param name="expression">表达式</param> /// <param name="codeBody">函数体</param> /// <returns>返回值object</returns> public object Eval(string expression,string codeBody) { msc.AddCode(codeBody); return msc.Eval(expression); } /// <summary> /// 运行Eval方法 /// </summary> /// <param name="language">脚本语言</param> /// <param name="expression">表达式</param> /// <param name="codeBody">函数体</param> /// <returns>返回值object</returns> public object Eval(ScriptLanguage language,string expression,string codeBody) { if(this.Language != language) this.Language = language; return Eval(expression,codeBody); } /// <summary> /// 运行Run方法 /// </summary> /// <param name="mainFunctionName">入口函数名称</param> /// <param name="parameters">参数</param> /// <param name="codeBody">函数体</param> /// <returns>返回值object</returns> public object Run(string mainFunctionName,object[] parameters,string codeBody) { this.msc.AddCode(codeBody); return msc.Run(mainFunctionName,ref parameters) }