C#-编写COM服务器-客户端上未触发事件

C#-编写COM服务器-客户端上未触发事件,c#,.net,events,com,vb6,C#,.net,Events,Com,Vb6,我在C#中实现了一个COM服务器,它有一个vb6客户端 当触发我的事件时,处理程序总是空的——看起来vb6应用程序从未订阅我的事件 vb6应用程序是一个现有的第三方应用程序,似乎不会给出任何错误消息 从COM客户端->服务器,普通方法工作正常 我能做些什么来调试正在发生的事情吗?或者为什么我的活动不起作用 下面是我的代码的一个快速示例片段: [ComVisible(true), Guid(Constants.CLASS_IID), ProgId(Const

我在C#中实现了一个COM服务器,它有一个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);
如果我尝试用我的C#com服务器替换/实现的现有ocx文件,事件将照常工作。它也是用vb6编写的,所以我的C#服务器中肯定有什么地方出错了

我还想补充一点,我尝试了ClassInterfaceType的所有3种设置,得到了相同的结果——尽管每次尝试都必须重新注册COM服务器

看看我生成的IDL,在我看来是正确的,而且一切似乎都与我试图重新创建的原始IDL非常相似,如果需要,我可以发布

更新:我拿出了旧的VisualStudio6,制作了一个VB6应用程序来测试我的C#COM服务器,它工作得很好

因此,我使用了一个免费的vb6反编译器,它可以将反编译的代码输出到vb6项目中,并在我想加载COM服务器的第三方应用程序上运行了它,结果发现它不起作用


我注意到他们的应用程序使用我的COM服务器作为设计器的控件,而我的测试程序只是以WithEvents的形式声明了一个成员变量。设计师在幕后有什么事情打破了这一点吗?如何使COM服务器ActiveX兼容?我还注意到VB6 ide不允许我将我的C#com服务器作为控件添加到工具箱中。

我隐约记得自己也有这个错误,就像运行时不知道如何将com注册映射到您的事件一样

我回去看看我做了什么,唯一的区别是委托定义在我的COM类中,我也看到了在这个类中发生的情况

因此,请尝试在MyClass中移动MyEventHandler,如下所示:

   [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);
    }

我是从控件而不是用户控件派生出来的,我看到了一个在C#中实现ActiveX控件的例子,这让我想到了这一点


显然,UserControl实现了一些接口,使其能够正常工作。。。谁知道…

您可能忘了添加 [程序集:Guid(“…”)] 对于您的项目,这意味着每次重新编译C#项目时COM中的TypeLib ID都会更改


如果没有该属性,编译器将生成不同的typelibrary,但某些COM函数在没有匹配库ID的情况下工作。

我找到了一个修复方法,允许我使用从控件继承的自定义控件(与UserControl相反)

在代码编辑器中,添加WithEvents变量的声明:

Dim WithEvents ControlNameEvents As ControlLibrary.ControlName
在表单_Load事件处理程序中,添加以下代码以初始化WithEvents变量:

Private Sub Form_Load()
    Set ControlNameEvents = Me.ControlNameOnVB6Form
End Sub
添加代码以在WithEvents变量的事件处理程序中处理自定义事件:

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

来源:

尝试得很好,但没有成功。我想知道他们的vb6代码是否做得不正确,不允许.Net CCW处理该事件。我也尝试过几种方法,添加一个snk,将程序集放在GAC中,而不是使用regasm/codebase,但似乎没有任何效果。然而,标准方法很好用。这是很久以前的事了。但我不认为这是问题所在。