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) }