C # - написание COM-сервера - события не запускаются на клиенте - PullRequest
0 голосов
/ 28 октября 2009

Я реализовал COM-сервер в C # с клиентом vb6.

При запуске моих событий обработчики всегда равны нулю - похоже, что приложение vb6 никогда не подписывается на мои события.

Приложение vb6 является существующим сторонним приложением и, по-видимому, не выдает сообщений об ошибках.

Обычные методы прекрасно работают с COM-клиента -> сервера.

Что я могу сделать, чтобы отладить происходящее? Или почему мои мероприятия не работают?

Вот небольшой пример моего кода:

    [ComVisible(true),
        Guid(Constants.CLASS_IID),
        ProgId(Constants.PROG_ID),
        ClassInterface(ClassInterfaceType.None),
        ComSourceInterfaces(typeof(IMyServiceEvents))]
    public class MyClass : Control, IMyService, IMyServiceEvents
    {
       [DispId(1)]
       public event MyEventHandler MyEvent;

       //... also implements IMyService, which is working
    }

    [ComVisible(true),
        InterfaceType(ComInterfaceType.InterfaceIsIDispatch),
        Guid(Constants.EVENTS_IID)]
    public interface IMyServiceEvents
    {
        [PreserveSig, DispId(1)]
        void MyEvent([In]int Status);
    }

    [ComVisible(false)]
    public delegate void MyEventHandler(int Status);

Если я пробую существующий ocx-файл, который пытаюсь заменить / внедрить на моем C # com-сервере, события будут работать как обычно. Он также написан на vb6, поэтому что-то на моем сервере C # должно быть не так.

Я также хочу добавить, что я попробовал все 3 настройки для ClassInterfaceType и получил те же результаты - хотя мне приходилось перерегистрировать свой COM-сервер для каждой попытки.

Глядя на мой сгенерированный IDL, он мне кажется правильным, и все кажется очень похожим на исходный IDL, который я пытаюсь воссоздать, я могу опубликовать, если мне нужно.

ОБНОВЛЕНИЕ: Я вытащил старую Visual Studio 6 и создал приложение VB6 для тестирования моего C # COM-сервера, и оно работало нормально.

Итак, я взял бесплатный декомпилятор vb6, который мог выводить декомпилированный код в проект vb6, и запустил его в стороннем приложении, которое я хочу загрузить на свой COM-сервер, - и увидел, что он не работает.

Я заметил, что их приложение использует мой COM-сервер в качестве элемента управления от дизайнера, и моя тестовая программа просто объявила переменную-член в форме как WithEvents. Что-то происходит за кулисами с дизайнером, который это ломает? Как я могу сделать мой COM-сервер ActiveX совместимым? Я также заметил, что VB6 ide не позволит мне добавить мой C # com сервер в панель инструментов в качестве элемента управления.

Ответы [ 4 ]

1 голос
/ 29 октября 2009

Я производил от Control, а не UserControl, я видел пример реализации элемента управления ActiveX в C #, который привел меня к этому.

Очевидно, UserControl реализует некоторый интерфейс, который делает эту работу правильно ... кто знает ...

1 голос
/ 28 октября 2009

Я смутно помню, что сам имел эту ошибку, как будто во время выполнения не знает, как сопоставить регистрацию COM с вашим событием.

Я вернулся к тому, что сделал, и единственное отличие, которое я вижу, состоит в том, что определение делегата находится внутри моего COM-класса, которое я также вижу в этом примере .

Поэтому попробуйте переместить MyEventHandler внутри MyClass, как показано ниже:

   [ComVisible(true),
        Guid(Constants.CLASS_IID),
        ProgId(Constants.PROG_ID),
        ClassInterface(ClassInterfaceType.None),
        ComSourceInterfaces(typeof(IMyServiceEvents))]
    public class MyClass : Control, IMyService, IMyServiceEvents
    {
       [ComVisible(false)]
       public delegate void MyEventHandler(int Status);

       [DispId(1)]
       public event MyEventHandler MyEvent;



       //... also implements IMyService, which is working
    }

    [ComVisible(true),
        InterfaceType(ComInterfaceType.InterfaceIsIDispatch),
        Guid(Constants.EVENTS_IID)]
    public interface IMyServiceEvents
    {
        [PreserveSig, DispId(1)]
        void MyEvent([In]int Status);
    }
0 голосов
/ 14 января 2019

Я нашел исправление для этого, которое позволило мне использовать свой пользовательский элемент управления, унаследованный от Control (в отличие от UserControl).

В редакторе кода добавьте объявление для переменной WithEvents:

Dim WithEvents ControlNameEvents As ControlLibrary.ControlName

В обработчик событий Form_Load добавьте следующий код для инициализации переменной WithEvents:

Private Sub Form_Load()
    Set ControlNameEvents = Me.ControlNameOnVB6Form
End Sub

Добавьте код для обработки вашего пользовательского события в обработчике события переменной WithEvents:

Private Sub ControlNameEvents_MyCustomEvent()
    MsgBox("My custom event fired")
End Sub

Источник: http://froque.github.io/VSIXInteropFormsToolkit/How%20To/Interop%20User%20Control%20Events.html

0 голосов
/ 31 августа 2016

Вы, вероятно, забыли добавить [сборка: Guid ("...")] в ваш проект, что означает, что ID TypeLib в COM изменяется каждый раз, когда вы перекомпилируете проект C #.

Без атрибута компилятор создаст другую библиотеку типов, но некоторые функции COM работают без совпадения идентификаторов библиотеки.

...