C# 从不执行外接程序事件

C# 从不执行外接程序事件,c#,events,visual-studio-2012,add-in,envdte,C#,Events,Visual Studio 2012,Add In,Envdte,我使用“Visual Studio加载项”向导创建了一个新的加载项项目,现在,我正在尝试添加一些事件处理程序: public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom) { _applicationObject = (DTE2)application; _addInInstance = (AddIn)addInInst;

我使用“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;
}
但无论我做什么,我的处理者永远不会被处决


我瞎了吗?我还需要做些什么来注册这些处理程序,或者为什么它不起作用?

看来你是垃圾收集器的受害者。见:


如果在调试器中查看applicationObject,您将看到它是COM对象,但xxxEvents类不是 (如果无法使代码在OnConnection上中断,则调试时可能没有加载加载项,请检查“工具”菜单)

COM中的事件由一个单独的COM接口(本例中有几个)在服务器(VS)调用的另一个方向上处理

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

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

我不确定,但我认为当您使用一个与事件接口有直接关联的COM对象时,这通常会起作用,因此这可能是由于DTE COM接口的结构

无论如何,正如其他人所说,您只需要对BuildEvents进行任何类型的托管引用,然后从app对象中选择Events和DocumentEvents类来修复它。VS的多个实例加载外接程序的单独实例,以便您只需添加静态对象引用列表并在OnConnect中设置它们


我也有同样的问题。。。。有时候。有时在部署时,事件会起作用。。有时不是。没有意义。对于BuildEvents:此API支持.NET Framework基础结构,不打算直接从代码中使用。仅限Microsoft内部使用。可能正在对应用程序对象进行垃圾收集?情况似乎并非如此。默认情况下,外接程序向导将使显示的
\u applicationObject
在类级别创建,而不是作为本地变量创建。是否也存储事件项?@Earlz哦,对了,我将事件处理程序注册到Events.DocumentEvents而不是我的字段。我无法在周三之前对此进行测试,因此,如果你说这解决了问题,我会立即将答案标记为已接受。只能说我在不久前创建Outlook时有过相同的经历Addin。开始使用公共对象模型(COM)时非常混乱。COM还有其他问题,所以我建议@main——先读一些教程。我对此感到非常沮丧。这个答案超过9000。
 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;
 }