1

最近我遇到了将事件从 .NET 公开到 COM 的问题。

我在这个例子中取得了成功(概念上取自http://blogs.msdn.com/andreww/archive/2008/10/13/exposing-events-from-managed-add-in-objects.aspx):

// 我们自定义事件的委托类型。

[ComVisible(false)]
public delegate void SomeEventHandler(object sender, EventArgs e);

// Outgoing (source/event) interface.
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IAddInEvents
{
    [DispId(1)]
    void SomeEvent(object sender, EventArgs e);
}

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces(typeof(IAddInEvents))]
public class AddInUtilities :
{       
    // Event field. This is what a COM client will hook up
    // their sink to.
    public event SomeEventHandler SomeEvent;

    inernal void FireEvent(object sender, EventArgs e)
    {
        if (SomeEvent != null)
        {
            SomeEvent(sender, e);
        }
    }
}

这很好用,因为 IAddInEvents 接口被定义为IDispatch。但是,我需要发布一个 IUnknown 事件源接口。我无法控制事件接口,因为它来自第三方库(也将是已发布事件的消费者)。每当我尝试挂钩事件时,VB 环境(我试图接收事件的地方)就会崩溃,第三方产品(ESRI ArcMap)使用的 VBA 环境也会崩溃。

我已经能够(部分)手动实现IConnectionPointContainer接口(COM 在后台使用它来处理事件),然后我能够接收事件并进入我的 IConnectionPointContainer 实现。但是,这对我来说似乎有点矫枉过正,我认为 .NET 中必须对此提供隐式支持。其次,通过这种方法,我立即失去了代表的支持。

有人对这个有经验么?提前致谢。

4

2 回答 2

2

很简单,您将无法做到这一点。Classic VB 不支持非自动化 COM(如您所见)。

您将必须有一个包装器,您可以将您的自动化实例传递给它将公开非自动化事件。您实际上将必须有两种不同的类型来处理事件的两个独立客户端(启用自动化和未启用自动化)。

于 2009-01-07T19:05:55.867 回答
1

好的,所以我已经能够通过实现经典的 COM IConnectionPointCointainer、IConnectionPoint 和 IConnection(加上枚举接口)来实现这一点。它没有集成到 .NET 委托/事件模型中,但可以工作。

于 2009-01-19T17:33:44.733 回答