Невозможно вызвать код C # из VBScript - ошибка ActiveX - PullRequest
5 голосов
/ 14 ноября 2009

Я пытаюсь вызвать метод, написанный на C # из VBScript.

Я выполнил почти все инструкции, которые могу найти в Интернете, и у меня все еще есть проблемы.

В частности, я получаю

Ошибка: компонент ActiveX не может создать объект

Код: 800A01AD

Пока я сделал следующее:

  1. Набор ComVisible(true)
  2. Зарегистрировано с использованием regasm /codebase
  3. Сильно назвал мою сборку
  4. Подтвердил, что находится в реестре и указывает на правильное местоположение
  5. Обнародовал класс
  6. Нет статических методов
  7. Сделал метод, который я хочу назвать public
  8. Есть конструктор без параметров
  9. Явно определил GUID

Мой VBScript выглядит так:

set oObject = CreateObject("TTTTTT.FFFFF.CCCCCCCCC")

Мой код C # выглядит так:

using System;
using System.IO;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace XXXXX.YYYYY
{
    [ComVisible(true)]
    [Guid("3EB62C37-79BC-44f7-AFBD-7B8113D1FD4F")]
    [ProgId("TTTTTT.FFFFF.CCCCCCCCC")]
    public class CCCCCCCCC
    {
        public void MyFunc()
        {
            //
        }
    }
}

Кто-нибудь может помочь?

Ответы [ 5 ]

4 голосов
/ 14 ноября 2009

В вашем коде нет ничего плохого, и вы следовали правильной процедуре установки. Однако полученный вами код ошибки ясно указывает на то, что интерпретатору сценария не удается найти или загрузить сборку. Лучший способ устранить это - использовать утилиту SysInternals ProcMon.

Я без проблем запустил ваш код, это были самые важные записи в журнале ProcMon:

22  12:04:41.1795038 PM WScript.exe 55280   RegOpenKey  HKCR\TTTTTT.FFFFF.CCCCCCCCC SUCCESS Desired Access: Read
26  12:04:41.1795682 PM WScript.exe 55280   RegOpenKey  HKCR\TTTTTT.FFFFF.CCCCCCCCC\CLSID   SUCCESS Desired Access: Read
29  12:04:41.1796996 PM WScript.exe 55280   RegQueryValue   HKCR\TTTTTT.FFFFF.CCCCCCCCC\CLSID\(Default) SUCCESS Type: REG_SZ, Length: 78, Data: {3EB62C37-79BC-44F7-AFBD-7B8113D1FD4F}
34  12:04:41.1797653 PM WScript.exe 55280   RegOpenKey  HKCR\CLSID\{3EB62C37-79BC-44F7-AFBD-7B8113D1FD4F}   SUCCESS Desired Access: Read
62  12:04:41.1802539 PM WScript.exe 55280   RegOpenKey  HKCR\CLSID\{3EB62C37-79BC-44F7-AFBD-7B8113D1FD4F}\InprocServer32    SUCCESS Desired Access: Read
71  12:04:41.1804181 PM WScript.exe 55280   RegQueryValue   HKCR\CLSID\{3EB62C37-79BC-44F7-AFBD-7B8113D1FD4F}\InprocServer32\(Default)  SUCCESS Type: REG_SZ, Length: 24, Data: mscoree.dll
824 12:04:41.2425662 PM WScript.exe 55280   RegQueryValue   HKCR\CLSID\{3EB62C37-79BC-44F7-AFBD-7B8113D1FD4F}\InprocServer32\1.0.0.0\CodeBase   SUCCESS Type: REG_SZ, Length: 124, Data: file:///c:/projects/ClassLibrary2/obj/Debug/ClassLibrary2.DLL
... Lots of .NET keys...
1239    12:04:41.2970169 PM WScript.exe 55280   CreateFile  C:\projects\ClassLibrary2\obj\Debug\ClassLibrary2.dll   SUCCESS Desired Access: Read Attributes, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, OpenResult: Opened
4 голосов
/ 14 ноября 2009

Вы читали эту статью: COM Interop Exposed

На последней странице (3) статьи есть список:

  1. Определение интерфейса .NET для методы, которые вы хотите выставить на COM.
  2. Назначьте GUID для этого интерфейса с атрибут "Guid".
  3. Пусть ваш класс реализует ваш интерфейс в качестве первого интерфейса.
  4. Назначьте GUID этому классу с помощью Атрибут "Guid".
  5. Добавить "ClassInterface(ClassInterfaceType.None)" атрибут для предотвращения regasm / tlbexp от создания пустого по умолчанию интерфейс.
  6. Жесткий код определенного номера версии в вашем атрибуте AssemblyVersion.
  7. Создать пару ключей строгого имени для ваше собрание и укажите на него через атрибут AssemblyKeyFile.
  8. Добавьте вашу сборку в GAC,
  9. Зарегистрируйте вашу сборку для COM используя команду REGASM вместе с опция / tlb для генерации COM библиотека типов.

Я не уверен, что GAC и ClassInterfaceType.None являются недостающими частями вашей головоломки, вы можете попробовать. Удачи!

2 голосов
/ 14 ноября 2009

Вот простой проект с несколькими шагами, чтобы вы начали.

C # код:

using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

[assembly:System.CLSCompliant(true)]
[assembly: ComVisible(true)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("7d9c5cd3-73d4-4ab1-ba98-32515256c0b0")]

namespace Cheeso.ComTests
{
    [Guid("7d9c5cd3-73d4-4ab1-ba98-32515256c0b1")]
    public class TestReply
    {
        public string salutation;
        public string name;
        public string time;
    }

    [Guid("7d9c5cd3-73d4-4ab1-ba98-32515256c0b2")]
    public class TestObj
    {
        // ctor
        public TestObj () {}

        public TestReply SayHello(string addressee)
        {
            return SayHello(addressee, "hello");
        }

        public TestReply SayHello(string addressee, string greeting)
        {
            string x = String.Format("{0}, {1}!", greeting, addressee);
            Console.WriteLine("{0}", x);

            TestReply r = new TestReply
            {
                salutation = greeting,
                name = addressee,
                time = System.DateTime.Now.ToString("u")
            };
            return r;
        }
    }
}

код клиента VBScript:

Function Main()
    Dim obj
    Dim reply
    set obj = CreateObject("Cheeso.ComTests.TestObj")
    Set reply = obj.SayHello("Evgeny")
    WScript.Echo "Reply at: " & reply.time
    Set reply = obj.SayHello_2("Evgeny", "wassup")
    WScript.Echo "Reply at: " & reply.time
End Function

Main

Для постройки:

(produce your .snk file, once)
csc.exe /t:library /debug+ /keyfile:Foo.snk /out:TestObj.dll TestObj.cs
regasm /codebase TestObj.exe

Затем просто запустите vbscript (через cscript.exe).

Как только вы освоите основную вещь, вы можете настроить ее, добавить GAC, сделать явную библиотеку типов, добавить явный ProgId и так далее.

ps. К вашему сведению, в этом примере показано, что происходит с перегруженными методами .NET в классе, зарегистрированном для взаимодействия. К имени метода добавлен неявный _2 (_3, _4 и т. Д.).

1 голос
/ 27 октября 2013

Чтобы пример Cheeso работал на 64-битной платформе, убедитесь, что вы вызываете CScript.exe как:

%windir%\SysWOW64\cscript.exe test.vbs

Ссылка: Невозможно использовать CreateObject из сценариев VB в Windows 7 x64

0 голосов
/ 17 декабря 2009

Может быть, все ваши проблемы вызваны VS. Попробуйте скомпилировать вашу библиотеку из командной строки, набрав

csc.exe /t:library AClass.cs /keyfile:Foo.snk - produce your key file with VS!
regasm /codebase /tlb AClass.dll

VS добавляет некоторые вещи, такие как / warn: / noconfig и так далее, а также добавляет ссылки на другие сборки, такие как System.Core и так далее, и иногда вызывает ошибки Для меня компиляция из csc сработала.

...