1

これは私の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): Program.cs の Srcipting.Program.CallVbsFunction(Object p) の MSScriptControl.IScriptControl.Run(String ProcedureName, Object[]& Parameters) での無効なプロシージャ呼び出しまたは引数

4

1 に答える 1

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 文字列のように見えますが、2 回目の外観では見えないことです。


文字列を直接登録する場合、または文字列を返す関数を登録する場合にのみ、このラッパーを使用する必要があります。文字列型のプロパティを持つオブジェクトを登録する場合は問題ありません。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
于 2016-05-17T13:21:35.237 に答える