到微软的网站上下载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
{
///
/// 脚本类型
///
public enum ScriptLanguage
{
///
/// JScript脚本语言
///
JScript,
///
/// VBscript脚本语言
///
VBscript,
///
/// JavaScript脚本语言
///
JavaScript
}
///
/// 脚本运行错误代理
///
public delegate void RunErrorHandler(,',',');
///
/// 脚本运行超时代理
///
public delegate void RunTimeoutHandler(,',',');
///
/// ScriptEngine类
///
public class ScriptEngine
{
private ScriptControl msc;
//定义脚本运行错误事件
public event RunErrorHandler RunError;
//定义脚本运行超时事件
public event RunTimeoutHandler RunTimeout;
///
///构造函数
///
public ScriptEngine():this(ScriptLanguage.VBscript)
{
}
///
/// 构造函数
///
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,',',');
}
///
/// 运行Eval方法
///
/// 返回值object
public object Eval(string expression,string codeBody)
{
msc.AddCode(codeBody,',',');
return msc.Eval(expression,',',');
}
///
/// 运行Eval方法
///
/// 返回值object
public object Eval(ScriptLanguage language,string expression,string codeBody)
{
if(this.Language != language)
this.Language = language;
return Eval(expression,codeBody,',',');
}
///
/// 运行Run方法
///
/// 返回值object
public object Run(string mainFunctionName,object[] parameters,string codeBody)
{
this.msc.AddCode(codeBody,',',');
return msc.Run(mainFunctionName,ref parameters,',',');
}
///
/// 运行Run方法
///
/// 返回值object
public object Run(ScriptLanguage language,string mainFunctionName,object[] parameters,string codeBody)
{
if(this.Language != language)
this.Language = language;
return Run(mainFunctionName,parameters,codeBody,',',');
}
///
/// 放弃所有已经添加到 ScriptControl 中的 Script 代码和对象
///
public void Reset()
{
this.msc.Reset(,',',');
}
///
/// 获取或设置脚本语言
///
public ScriptLanguage Language
{
get{return (ScriptLanguage)Enum.Parse(typeof(ScriptLanguage),this.msc.Language,false,',',');}
set{this.msc.Language = value.ToString(,',',');}
}
///
/// 获取或设置脚本执行时间,单位为毫秒
///
public int Timeout
{
get{return this.msc.Timeout;}
set{this.msc.Timeout = value;}
}
///
/// 设置是否显示用户界面元素
///
public bool AllowUI
{
get{return this.msc.AllowUI;}
set{this.msc.AllowUI = value;}
}
///
/// 宿主应用程序是否有保密性要求
///
public bool UseSafeSubset
{
get{return this.msc.UseSafeSubset;}
set{this.msc.UseSafeSubset = true;}
}
///
/// RunError事件激发
///
private void OnError()
{
if(RunError!=null)
RunError(,',',');
}
///
/// OnTimeout事件激发
///
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
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的朋友进行交流,我的邮件地址
zhzuocn@163.com
关键字词: