永远不会执行加载项事件

时间:2013-01-04 22:16:49

标签: c# events visual-studio-2012 add-in envdte

我使用“Visual Studio的加载项”向导来创建一个新的Addin项目,现在,我正在尝试添加一些事件处理程序:

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

但无论我做什么,我的处理程序都不会执行!

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

2 个答案:

答案 0 :(得分:21)

您似乎是垃圾收集器的受害者。请参阅: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;
 }

答案 1 :(得分:1)

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

COM中的事件由另一个COM接口处理(在这种情况下为几个),服务器(VS)调用它来触发它们。

尽管COM对象具有与CLR程序集类似的类型化程序集概念,但它们在内部是非托管代码,因此无法将根目录保存到托管对象

因此,尽管您可以以与本机CLR事件完全相似的方式将委托挂钩到COM事件,但您的事件将挂钩到RCW(运行时可调用包装器)。 从服务器到RCW com接口有一个COM引用,但是如果没有CLR根,RCW最终会被卸载,卸载com接口,之后你就不会引发任何事件。

我不确定,但我认为这通常适用于您使用与其事件接口直接关联的单个COM对象,因此可能是由于DTE COM接口的结构...

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

Subscription to DTE events doesn't seem to work - Events don't get called

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