C# run VBScript with MSScriptControl AddObject with string failed

萝らか妹 提交于 2019-12-24 14:53:15

问题


This is my C# program:

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());
        }
    }
}

My VBScript file contents:

Function Test(a)
    MsgBox myguid
End Function

And Finally this is my exception when I use AddObject() with string object:

System.Runtime.InteropServices.COMException (0x800A0005): Invalid procedure call or argument at MSScriptControl.IScriptControl.Run(String ProcedureName, Object[]& Parameters) at Srcipting.Program.CallVbsFunction(Object p) in Program.cs


回答1:


You need to use a wrapper object that is 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"));

The problem is that the .net String object looks like a native vb string to the MSScriptControl on the first look but not on the second look.


You only need to use this wrapper when you register a string directly or register a function that returns a string. There is no problem when registering an object that has properties of type string. There is also no problem for the parameters you pass to Run() because these will be correctly marshaled to native vb strings by the .net runtime.


So the maybe best option is to not provide individual strings to your script but an object that encapsulates all the different values you want it to use.

Define this class

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

Then construct the object and set all the properties and register it with the script control

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

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

You can then use it in your script like this:

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


来源:https://stackoverflow.com/questions/37213451/c-sharp-run-vbscript-with-msscriptcontrol-addobject-with-string-failed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!