加载项事件永远不会执行

本文关键字:执行 永远 事件 加载项 | 更新日期: 2023-09-27 17:50:47

我使用" add - in for Visual Studio"向导创建了一个新的插件项目,现在,我正在尝试添加一些事件处理程序:

public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
{
    _applicationObject = (DTE2)application;
    _addInInstance = (AddIn)addInInst;
    _applicationObject.Events.BuildEvents.OnBuildBegin += BuildEvents_OnBuildBegin;
    _applicationObject.Events.BuildEvents.OnBuildDone += BuildEvents_OnBuildDone;
    _applicationObject.Events.SelectionEvents.OnChange += SelectionEvents_OnChange;
    _applicationObject.Events.DocumentEvents.DocumentOpened += DocumentEvents_DocumentOpened;
    _applicationObject.Events.DocumentEvents.DocumentSaved += DocumentEvents_DocumentSaved;
}

但是无论我做什么,我的处理程序永远不会被执行!

我瞎了吗?我是否必须做其他事情来注册这些处理程序,或者为什么它不起作用?

加载项事件永远不会执行

看来你是垃圾收集器的受害者。参见:http://www.mztools.com/articles/2005/mz2005012.aspx

 private readonly BuildEvents _buildEvents;
 private readonly SelectionEvents _selectionEvents;
 private readonly DocumentEvents _documentEvents;
 private readonly Events _events;
 public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
 {
     _applicationObject = (DTE2)application;
     _addInInstance = (AddIn)addInInst;
     _events = _applicationObject.Events;
     _buildEvents = _events.BuildEvents;
     _buildEvents.OnBuildBegin += BuildEvents_OnBuildBegin;
     _buildEvents.OnBuildDone += BuildEvents_OnBuildDone;
     _selectionEvents = _events.SelectionEvents;
     _selectionEvents.OnChange += SelectionEvents_OnChange;
     _documentEvents = _events.DocumentEvents;
     _documentEvents.DocumentOpened += DocumentEvents_DocumentOpened;
     _documentEvents.DocumentSaved += DocumentEvents_DocumentSaved;
 }

如果您查看调试器中的applicationObject,您将看到它是一个COM对象,但xxxEvents类不是(如果你不能让代码在OnConnection上中断,那么可能是你的插件在调试时没有被加载,检查工具菜单)

COM中的事件由服务器(VS)调用的另一个方向上的单独的COM接口(在这种情况下是几个)处理以触发它们。

虽然COM对象具有与CLR程序集相似的类型程序集概念,但它们在内部是非托管代码,因此不能包含托管对象的根。

因此,尽管您可以以一种看起来完全像本机CLR事件的方式将委托挂钩到COM事件,但您的事件被挂钩到RCW(运行时可调用的包装器)。有一个从服务器到RCW COM接口的COM引用,但是没有CLR根,RCW最终会被处理,从而卸载COM接口,之后您将不会接收任何事件。

我不确定,但我认为这通常是有效的,当你消费一个单一的COM对象与它的事件接口直接关联,所以它可能是由于如何DTE COM接口的结构…

无论如何,正如其他人所说,你只需要从应用对象中对BuildEvents, SelectionEvents和documenttevents类进行任何类型的托管引用来修复它。VS的多个实例加载add的单独实例,所以你可以只添加一个静态对象refs列表并在OnConnect中设置它们。

订阅DTE事件似乎不起作用-事件没有被调用

http://msdn.microsoft.com/en-us/library/k639e386.aspx