【问题标题】:Add-In events are never executed加载项事件永远不会执行
【发布时间】:2013-01-04 22:16:48
【问题描述】:

我使用“Add-In for 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;
}

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

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

【问题讨论】:

  • 我也有同样的问题....有时。有时当我部署时,事件会起作用..有时不会。没有意义。
  • 对于 BuildEvents:此 API 支持 .NET Framework 基础结构,不能直接从您的代码中使用。仅限 Microsoft 内部使用。
  • 也许 _applicationObject 正在被垃圾收集?

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


【解决方案1】:

看来你是垃圾收集器的受害者。见: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,而不是作为局部变量
  • 您是否也存储了事件项?
  • @Earlz 哦,对,我将事件处理程序注册到 Events.DocumentEvents 而不是我的字段。我将无法在星期三之前对此进行测试,因此如果您说这可以解决问题,我会立即将答案标记为已接受。
  • 只能说我之前在创建 Outlook 插件时也有过同样的经历。通用对象模型 (COM) 起初使用起来非常混乱。 COM 还有其他一些问题,所以我建议@main-- 先阅读一些教程。
  • 我对此感到非常沮丧。这个答案超过9000。
【解决方案2】:

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

COM 中的事件由单独的 COM 接口(在本例中为多个)在服务器 (VS) 调用以触发它们的另一个方向上处理。

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

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

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

无论如何,正如其他人所说,您只需要从应用程序对象中对 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-25
    • 1970-01-01
    • 2019-12-07
    • 1970-01-01
    • 1970-01-01
    • 2020-01-23
    • 2021-08-19
    相关资源
    最近更新 更多