2016-05-13 2 views
1

Это мой C# программа:C# запустить VBScript с MSScriptControl AddObject шпагатом не удалось

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 ИмяПроцедуры, Object [] & Параметров) при Srcipting.Program.CallVbsFunction (Объект р) в Program.cs

+0

Одиночная версия кавычек передает символы 'char', поскольку двойные кавычки передают строку' string' wh ich является _array_ символов –

+0

Да, моя проблема в том, что я использую String, я знаю, что VBScript использует VARIANT и BSTR. Если я вызываю MsgBox, имя_файла (myguid) возвращает «String», но не работает. – themadmax

+0

Что произойдет, если вы используете 'sc.AddObject (« myguid », p [0], false);' –

ответ

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 строка выглядит как родной Vb строки в MSScriptControl на первый взгляд, но не на второй взгляд.


Вам нужно использовать эту оболочку только при регистрации строки напрямую или регистрации функции, которая возвращает строку. При регистрации объекта, имеющего свойства строки типа, нет проблем. Также нет проблем для параметров, которые вы передаете Run(), потому что они будут корректно привязаны к родным vb-строкам с помощью .net runtime.


Так что, возможно, лучший вариант, чтобы не предоставлять отдельные строки в сценарий, но объект, который инкапсулирует все различные значения, которые вы хотите его использовать.

Определить этот класс

[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 
+0

Я действительно не понимаю, что объект .net String выглядит как родная строка vb для MSScriptControl при первом взгляде но не на втором взгляде ». Но решение для меня работает. – themadmax

+0

Я не знаю деталей, но это то, что мне кажется. – NineBerry