1

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

3
  • The single quotes version is passing a char wheres as the double quotes is passing a string which is an array of chars Commented May 13, 2016 at 15:12
  • Yes my problem is when I use String, I know VBScript use VARIANT and BSTR, If I call MsgBox typename(myguid) is returning "String" but not work. Commented May 13, 2016 at 15:30
  • What happens if you use sc.AddObject("myguid", p[0], false); Commented May 13, 2016 at 15:34

1 Answer 1

2

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
Sign up to request clarification or add additional context in comments.

2 Comments

I don't really understand "the .net String object looks like a native vb string to the MSScriptControl on the first look but not on the second look.". But you solution work for me.
I don't know the details, but this is what it looks like to me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.