C#运行VBScript与MSScriptControl AddObject与字符串失败

时间:2016-05-13 15:04:36

标签: c# vbscript msscriptcontrol

这是我的C#程序:

class Program
{
    static void Main(string[] args)
    {
        CallVbsFunction(1); //Work
        CallVbsFunction(1.2); //Work
        CallVbsFunction('a'); //Work
        CallVbsFunction("a"); //!!Exception see bellow
    }

    private static void CallVbsFunction(object p)
    {
        var sc = new MSScriptControl.ScriptControl();
        sc.Language = "VBScript";
        sc.AllowUI = true;

        try
        {         
            sc.AddCode(System.IO.File.ReadAllText("script.vbs"));
            sc.AddObject("myguid", p, false);
            var parameters = new object[] { "a" };
            sc.Run("test", ref parameters);
        }
        catch (Exception e)
        {
            Console.Out.WriteLine(e.ToString());
        }
    }
}

我的VBScript文件内容:

Function Test(a)
    MsgBox myguid
End Function

最后,当我使用带有字符串对象的AddObject()时,这是我的异常:

  

System.Runtime.InteropServices.COMException(0x800A0005):无效   程序调用或参数   MSScriptControl.IScriptControl.Run(String ProcedureName,Object []&   参数)在Srcipting.Program.CallVbsFunction(Object p)中   Program.cs的

1 个答案:

答案 0 :(得分:2)

您需要使用ComVisible的包装器对象:

[ComVisible(true)]
public class StringWrapper
{
    private string wrappedString;

    public StringWrapper(string value)
    {
        wrappedString = value;
    }

    public override string ToString()
    {
        return wrappedString;
    }
}

CallVbsFunction(new StringWrapper("a"));

问题是.net String对象在第一次看时看起来像MSScriptControl的本机vb字符串,但在第二次看上去看起来不像。

直接注册字符串或注册返回字符串的函数时,只需使用此包装器。注册具有string类型属性的对象时没有问题。您传递给Run()的参数也没有问题,因为这些参数将被.net运行时正确封送到本机vb字符串。

因此,最好的选择是不向脚本提供单独的字符串,而是封装您希望它使用的所有不同值的对象。

定义此类

[ComVisible(true)]
public class HostOptions
{
    public string OptionA { get; set; }
    public string OptionB { get; set; }
}

然后构造对象并设置所有属性并使用脚本控件

注册它
var hostOptions = new HostOptions();
hostOptions.OptionA = "AAA";
hostOptions.OptionB = "BBB";

sc.AddObject("HostOptions", hostOptions, false);

然后您可以在脚本中使用它:

Function Test(a)
    MsgBox HostOptions.OptionA
    MsgBox HostOptions.OptionB
End Function