到微軟的網站上下載windows script control,它是一個activex(r) 控件,所以在.net中使用我interop了一下。下載安裝完成后,新建一個c#的windows應用程序項目,在解決方案資源管理器中選中引用節點,右鍵點擊選擇添加引用菜單,彈出添加引用對話框,單擊瀏覽找到安裝windows script control的目錄,選取msscript.ocx文件確定。那么在引用節點下會增加一個msscriptcontrol組件,下面是他interop后的所有對象。
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);
}
/// <summary>
/// 運行run方法
/// </summary>
/// <param name="language">腳本語言</param>
/// <param name="mainfunctionname">入口函數名稱</param>
/// <param name="parameters">參數</param>
/// <param name="codebody">函數體</param>
/// <returns>返回值object</returns>
public object run(scriptlanguage language,string mainfunctionname,object[] parameters,string codebody)
{
if(this.language != language)
this.language = language;
return run(mainfunctionname,parameters,codebody);
}
/// <summary>
/// 放棄所有已經添加到 scriptcontrol 中的 script 代碼和對象
/// </summary>
public void reset()
{
this.msc.reset();
}
/// <summary>
/// 獲取或設置腳本語言
/// </summary>
public scriptlanguage language
{
get{return (scriptlanguage)enum.parse(typeof(scriptlanguage),this.msc.language,false);}
set{this.msc.language = value.tostring();}
}
/// <summary>
/// 獲取或設置腳本執行時間,單位為毫秒
/// </summary>
public int timeout
{
get{return this.msc.timeout;}
set{this.msc.timeout = value;}
}
/// <summary>
/// 設置是否顯示用戶界面元素
/// </summary>
public bool allowui
{
get{return this.msc.allowui;}
set{this.msc.allowui = value;}
}
/// <summary>
/// 宿主應用程序是否有保密性要求
/// </summary>
public bool usesafesubset
{
get{return this.msc.usesafesubset;}
set{this.msc.usesafesubset = true;}
}
/// <summary>
/// runerror事件激發
/// </summary>
private void onerror()
{
if(runerror!=null)
runerror();
}
/// <summary>
/// ontimeout事件激發
/// </summary>
private void ontimeout()
{
if(runtimeout!=null)
runtimeout();
}
private void scriptengine_error()
{
onerror();
}
private void scriptengine_timeout()
{
ontimeout();
}
}
}
上面的包裝定義了一個scriptlanguage枚舉,這樣操作起來更方便一點。另外腳本引擎包括了error事件和timeout事件,根據實際使用情況可進行注冊。
二.腳本引擎演示
我建了個窗體程序,測試包括腳本語言的選擇,是否開啟allowui屬性,超時時間的設置,以及腳本引擎調用方法的選擇。測試程序代碼比較長,下面列出了主要部分:
using system;
using system.drawing;
using system.collections;
using system.componentmodel;
using system.windows.forms;
using system.data;
namespace zz
{
public class form1 : system.windows.forms.form
{
private scriptengine scriptengine;
private system.windows.forms.checkbox checkboxallowui;
private system.windows.forms.textbox textboxresult;
private system.windows.forms.numericupdown numericupdowntimeout;
private system.windows.forms.textbox textboxcodebody;
private system.windows.forms.button buttonrun;
private system.windows.forms.button buttoncancel;
private system.windows.forms.combobox comboboxscript;
private system.windows.forms.textbox textboxparams;
private system.windows.forms.radiobutton radiobuttoneval;
private system.windows.forms.radiobutton radiobuttonrun;
private system.windows.forms.textbox textboxmethodname;
private system.componentmodel.container components = null;
public form1()
{
initializecomponent();
this.comboboxscript.selectedindex = 0;
this.scriptengine = new scriptengine();
this.scriptengine.usesafesubset = true;
this.scriptengine.runerror += new runerrorhandler(scriptengine_runerror);
this.scriptengine.runtimeout += new runtimeouthandler(scriptengine_runtimeout);
}
protected override void dispose( bool disposing )
{
if( disposing )
if (components != null)
components.dispose();
base.dispose( disposing );
}
#region windows 窗體設計器生成的代碼
private void initializecomponent()
{
//省略
}
#endregion
[stathread]
static void main()
{
application.run(new form1());
}
//運行腳本
private void buttonrun_click(object sender, system.eventargs e)
{
this.scriptengine.reset();
this.scriptengine.language = (scriptlanguage)enum.parse(typeof(scriptlanguage),this.comboboxscript.selecteditem.tostring());
this.scriptengine.timeout = (int)this.numericupdowntimeout.value;
this.scriptengine.allowui = this.checkboxallowui.checked;
if(this.radiobuttoneval.checked)//執行eval方法
{
this.textboxresult.text = this.scriptengine.eval(this.textboxmethodname.text+"("+this.textboxparams.text+")",this.textboxcodebody.text).tostring();
}
else//執行run方法
{
string[] parameters = (string[])this.textboxparams.text.split(',');
object [] paramarray = new object[parameters.length];
for(int i = 0;i<parameters.length;i++)
paramarray[i] = int32.parse(parameters[i]);
this.textboxresult.text = this.scriptengine.run(this.textboxmethodname.text,paramarray,this.textboxcodebody.text).tostring();
}
}
//退出程序
private void buttoncancel_click(object sender, system.eventargs e)
{
this.close();
}
//錯誤函數
private void scriptengine_runerror()
{
messagebox.show("runerror執行腳本錯誤!");
}
private void scriptengine_runtimeout()
{
messagebox.show("runtimeout執行腳本超時,引發錯誤!");
}
}
}
下面是測試程序運行界面:
在文本框中寫了一個javascript的函數。輸入12,輸出12000012。
如果把超時時間調整為1毫秒,那么執行該腳本就會跳出下面的超時提醒框,同時激發事件。
總結,上面演示了javascript腳本,如果有興趣讀者可以寫一些vbsript函數進行測試,腳本語言也只列出了三種,看了幫助,他還支持其他一些腳本,如果需要可以添加。另外,因為是調用com,有些返回值是obejct類型的,需要進行轉換。在csdn的技術論壇c#板塊下時常有朋友問這方面的問題,對于碰到這類問題的朋友,希望通過這篇文章能獲得一些你需要的幫助,很高興能和搞.net的朋友進行交流,我的郵件地址[email protected]