简体   繁体   English

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

[英]C# - writing a COM server - events not firing on client

I have implemented a COM server in C#, that has a vb6 client. 我已经用C#实现了一个具有vb6客户端的COM服务器。

When going to fire my events, the handlers are always null--it appears that the vb6 app never subscribes to my events. 当要触发我的事件时,处理程序始终为空-看来vb6应用从未订阅我的事件。

The vb6 application is an existing 3rd party app, and appears to give no error messages. vb6应用程序是现有的第三方应用程序,似乎未显示任何错误消息。

Normal methods work just fine from COM client -> server. 普通方法可以从COM客户端->服务器正常工作。

Is there anything I can do to debug what is going on? 我可以做些什么来调试正在发生的事情吗? Or why my events are not working? 还是为什么我的活动无法正常进行?

Here is a quick example snippet of my code: 这是我的代码的一个简单示例片段:

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

If I try the existing ocx file that I'm trying to replace/implement with my C# com server, the events work as usual. 如果我尝试使用C#com服务器替换/实现现有的ocx文件,则事件将照常运行。 It is written in vb6 as well, so something in my C# server must be wrong. 它也是用vb6编写的,因此我的C#服务器中一定有问题。

I also want to add that I tried all 3 settings for ClassInterfaceType, and got the same results--although I had to re-register my COM server for each try. 我还想补充一点,我尝试了ClassInterfaceType的所有3种设置,并且得到了相同的结果-尽管每次尝试都必须重新注册COM服务器。

Looking at my generated IDL, it looks correct to me, and everything seems to be very similar to the original IDL I'm trying to recreate, I can post if I need to. 查看我生成的IDL,对我来说看起来是正确的,并且一切似乎都与我尝试重新创建的原始IDL非常相似,如果需要,可以发布。

UPDATE: Well I pulled out the old Visual Studio 6, and made a VB6 application to test my C# COM server, and it worked fine. 更新:好吧,我拿出旧的Visual Studio 6,并制作了一个VB6应用程序来测试我的C#COM服务器,它运行良好。

So I took a free vb6 decompiler that could output the decompiled code to a vb6 project, and ran it on the 3rd party app that I want to load my COM server--and saw it didn't work. 因此,我使用了一个免费的vb6反编译器,该反编译器可以将反编译的代码输出到vb6项目中,并在要加载COM服务器的第3方应用程序上运行-看到它不起作用。

I noticed that their application is using my COM server as a control from the designer, and my test program merely declared a member variable in the form as WithEvents. 我注意到他们的应用程序正在使用我的COM服务器作为设计者的控件,而我的测试程序只是将成员变量声明为WithEvents。 Is there something going on behind the scenes with the designer that is breaking this? 设计师在幕后发生了什么事情来打破这一点? How can I make my COM server ActiveX compatible? 如何使我的COM服务器ActiveX兼容? I also notice that the VB6 ide won't let me add my C# com server to the toolbox as a control. 我还注意到,VB6 ide不允许我将C#com服务器添加到工具箱中作为控件。

I vaguely remember having this error myself, it's like the run time doesn't know how to map the COM registration to your event. 我隐约记得自己有这个错误,就像运行时不知道如何将COM注册映射到您的事件一样。

I went back to look at what I did an the only difference I can see is that the delegate definition is inside my COM class which I also see occurring in this example . 我回过头来看看我做了什么,唯一能看到的就是委托定义在我的COM类内部,在这个示例中也看到了这种情况

So try moving the MyEventHandler inside of MyClass as below: 因此,尝试将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);
    }

I was deriving from Control, not UserControl, I saw an example of implementing an ActiveX control in C# that brought me to this. 我来自Control,而不是UserControl,我看到了一个用C#实现ActiveX控件的示例。

Apparently UserControl implements some interface that makes this work correctly... who knows... 显然,UserControl实现了一些使该功能正常工作的界面...谁知道...

You probably have forgot to add [assembly: Guid("...")] to your project, which means the TypeLib ID in COM changes everytime you recompile the C# project. 您可能忘记了将[assembly:Guid(“ ...”)]添加到项目中,这意味着每次您重新编译C#项目时,COM中的TypeLib ID都会更改。

Without the attribute, the compiler will produce a different typelibrary, but some COM functions works without matching library ids. 没有该属性,编译器将生成不同的类型库,但是某些COM函数在不匹配库ID的情况下工作。

I found a fix for this which allowed me to use my custom control which inherited from Control (as opposed to UserControl). 我找到了针对此问题的修复程序,该修复程序使我可以使用从Control(而不是UserControl)继承的自定义控件。

In the Code Editor, add a declaration for a WithEvents variable: 在代码编辑器中,为WithEvents变量添加一个声明:

Dim WithEvents ControlNameEvents As ControlLibrary.ControlName

In the Form_Load event handler, add the following code to initialize the WithEvents variable: 在Form_Load事件处理程序中,添加以下代码以初始化WithEvents变量:

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

Add code to handle your custom event in the WithEvents variable's event handler: 在WithEvents变量的事件处理程序中添加代码以处理您的自定义事件:

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

Source: http://froque.github.io/VSIXInteropFormsToolkit/How%20To/Interop%20User%20Control%20Events.html 来源: http : //froque.github.io/VSIXInteropFormsToolkit/How%20To/Interop%20User%20Control%20Events.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM