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)
{
this
.textBoxResult.Text =
this
.scriptEngine.Eval(
this
.textBoxMethodName.Text+
"("
+
this
.textBoxParams.Text+
")"
,
this
.textBoxCodeBody.Text).ToString();
}
else
{
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执行脚本超时,引发错误!"
);
}
}
}