在集成式视觉处理软件中,我们常需要使用脚本来控制流程或者灵活的计算结果,这常常要求我们在程序中能够嵌入执行脚本代码,而微软的MSScriptControl控件就为这样的需求提供了方便。
MSScriptControl控件是一个COM控件,可以通过VS引用进来。在解决方案的引用目录上单击右键,选择添加引用…-->COM标签-->选择 MicroSoft Script Control 1.0,将控件添加到项目中。使用using MSScriptControl引入命名空间。
一段实例代码如下所示:
string strProgram;
strProgram = "Sub Main\r\nMsgBox \"Hello world!\"\r\nEnd Sub";
ScriptControl sc=new ScriptControl();
sc.Language="VBScript";
sc.Reset();
sc.AddCode(strProgram);
object[] parameters=new object[0];
sc.Run("Main", parameters);
Console.ReadKey();
一些注意点:
1、在网上有看到定义的ScriptControl为ScriptControlClass类型的代码,我在实际使用过程中发现这样的定义会报错,“无法嵌入互操作类型“MSScriptControl.ScriptControlClass”。请改用适用的接口。”。需要将MSScriptControl的“嵌入互操作类型 ”属性更改为false,表示不将COM中的类型嵌入到C#程序集中。
2、ScriptControl有一个Error属性,包含了脚本代码的一些错误,像错误的行号、错误描述等,但是在异常中使用int errLine = sc.Error.Line;会报错,“MSScriptControl.IScriptControl.Error”与“MSScriptControl.DScriptControlSource_Event.Error”之间存在二义性,这是因为ScriptControl同时继承IScriptControl接口和DScritptControlSource_Event接口,而这两个接口中都定义了Error属性。解决这个问题的方法是使用强制类型转换告诉编译器要使用的接口类型,即使用int errLine= ((IScriptControl)sc).Error.Line;。
3、如果执行的VBScript是一个Sub过程,即没有参数的过程,则IScriptControl的Run方法的第二参数需使用object[] parameters=new object[0]来初始化。如果脚本是一个Function过程的话,parameters中应存放function过程的实参。
4、VBScript脚本中,变量不需要声明其类型。例如,Function Add(a,b)是一个可以接受的声明,而Function(a As Integer, b As Integer) As Integer则会报脚本错误。
5、需要通过AddObject方法为脚本传入外部对象时,需要设计ComVisible,把 Properties ->AssemblyInfo.cs -> [assembly: ComVisible(false)] 改为 [assembly: ComVisible(true)]。
6、MSScriptControl的AddObject方法可以向MSScritptControl中添加C#的对象,需要注意的是这个C#对象的类型声明(即这个对象的class)必须是public的,否则运行中会抛出“指定的转换无效”的异常。
下面的VBScript代码传入this指针,因此可以初始化窗体的Text的属性为当前时间。

