将事件从 .NET 公开到 COM

发布于 2024-07-11 04:07:34 字数 1535 浏览 6 评论 0原文

最近,我在将事件从 .NET 暴露到 COM 时遇到了问题。

我已经成功地完成了这个示例(概念上取自http://blogs.msdn.com/andreww/archive/2008/10/13/exusing-events-from-management-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 中必须对此有隐式支持。 其次,通过这种方法,我立即失去了代表的支持。

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

recently I have been encountering problems with exposing events from .NET to COM.

I have been successful with this example (conceptually taken from http://blogs.msdn.com/andreww/archive/2008/10/13/exposing-events-from-managed-add-in-objects.aspx):

// The delegate type for our custom event.

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

This works fine, because the IAddInEvents interface is defined as IDispatch. However, I need to publish an event source interface which is IUnknown. I do not have control over the event interface as it comes from a third-party library (which will also be the consumer of the published events). Whenever I try to hook to the events, VB environment (where I am trying to sink the events) crashes, so does the VBA environment which the third-party product (ESRI ArcMap) uses.

I have been able to (partially) implement IConnectionPointContainer interface (which COM uses in the background to handle events) manually, then I am able to sink the event and step into my IConnectionPointContainer implementation. However, this seems like an overkill to me and I think that there must an implicit support for this in .NET. Second, with this approach I instantly lose the delegate support.

Does anyone have any experience with this?
Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

默嘫て 2024-07-18 04:07:34

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

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

Quite simply, you won't be able to do this. Classic VB does not support non-Automation COM (as you have seen).

You will have to have a wrapper that you can pass your Automation instance to which will public the non-Automation event. You are effectively going to have to have two separate types to handle the two separate clients for the events (Automation-enabled and non-Automation enabled).

自控 2024-07-18 04:07:34

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

Ok, so I have been able to this by implementing the classic COM IConnectionPointCointainer, IConnectionPoint and IConnection (plus the enumeration interfaces). It does not integrate into the .NET delegate/event model, but works.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文