Visual studio 订阅DTE活动不需要';似乎不起作用-事件不起作用';我没接到电话
我在一个包中做了一个扩展,我正在调用以下代码(当用户按下工具栏中的按钮时发生): 第一个也是主要的问题是,对事件的订阅不起作用。我试过:Visual studio 订阅DTE活动不需要';似乎不起作用-事件不起作用';我没接到电话,visual-studio,visual-studio-2010,vsx,Visual Studio,Visual Studio 2010,Vsx,我在一个包中做了一个扩展,我正在调用以下代码(当用户按下工具栏中的按钮时发生): 第一个也是主要的问题是,对事件的订阅不起作用。我试过: 打开新文档 从调试分离(因此可能触发OnInterDesignMode 保存文档 所有这些似乎都没有任何效果,而且从未调用回调函数 第二个问题是,对事件行的订阅通常有效(订阅本身,回调不按上述方式工作),但在运行订阅行一段时间后有效,例如: _dte.Events.DebuggerEvents.OnEnterBreakMode -= DebuggerEve
- 打开新文档
- 从调试分离(因此可能触发OnInterDesignMode
- 保存文档
_dte.Events.DebuggerEvents.OnEnterBreakMode -= DebuggerEvents_OnEnterBreakMode;
导致异常:
Exception occured!
System.Runtime.InteropServices.InvalidComObjectException: COM object that has been separated from its underlying RCW cannot be used.
at System.StubHelpers.StubHelpers.StubRegisterRCW(Object pThis, IntPtr pThread)
at System.Runtime.InteropServices.UCOMIConnectionPoint.Unadvise(Int32 dwCookie)
at EnvDTE._dispDebuggerEvents_EventProvider.remove_OnEnterDesignMode(_dispDebuggerEvents_OnEnterDesignModeEventHandler A_1)
欢迎提出任何意见
谢谢!
Vitaly发布了一篇我从MSDN论坛上获得的由Ryan Molden撰写的文章,以防对任何人都有帮助:
我相信这里的问题是
CLR处理COM端点(事件
如果我没记错的话
你击中了目标
_applicationObject.Events.DebuggerEvents
CLR将成为您“链”的一部分
为创建新的DebuggerEvents对象
属性无法访问,并且不会缓存
它,因此它会回到你,你
向其注册一个事件处理程序(其中
在
临时对象和您的对象到期
给代表,但不是从您的
对象的临时对象,该临时对象
会阻止GC),那么你就不会
将该对象存储在任意位置,使其保持原样
立即合格并将
最终被GC’ed
我更改了代码,将DebuggerEvents存储为一个字段,一切都开始正常工作。下面是使用代码的方法:
// list where we will place events.
// make sure that this variable is on global scope so that GC does not delete the evvents
List<object> events = new List<object>();
public void AddEvents(EnvDTE dte)
{
// create an event when a document is open
var docEvent = dte.Events.DocumentEvents;
// add event to list so that GC does not remove it
events.Add(docEvent );
docEvent.DocumentOpened += (document)=>{
Console.Write("document was opened!");
};
// you may add more events:
var commandEvent = dte.Events.CommandEvents;
events.Add(commandEvent );
commandEvent.AfterExecute+= etc...
}
//列出我们将放置事件的位置。
//确保此变量在全局范围内,以便GC不会删除EVENTS
列表事件=新列表();
公共空间附加事件(EnvDTE dte)
{
//打开文档时创建事件
var docEvent=dte.Events.DocumentEvents;
//将事件添加到列表中,以便GC不会删除它
添加(docEvent);
docEvent.DocumentOpened+=(文档)=>{
编写(“文档已打开!”);
};
//您可以添加更多事件:
var commandEvent=dte.Events.CommandEvents;
添加(commandEvent);
commandEvent.AfterExecute+=等。。。
}
您节省了我2天的工作。在我的包中:私有静态解决方案事件解决方案事件;受保护覆盖无效初始化(){ApplicationObject=GetService(typeof(DTE))为DTE2;解决方案事件=ApplicationObject.Events.SolutionEvents;}
// list where we will place events.
// make sure that this variable is on global scope so that GC does not delete the evvents
List<object> events = new List<object>();
public void AddEvents(EnvDTE dte)
{
// create an event when a document is open
var docEvent = dte.Events.DocumentEvents;
// add event to list so that GC does not remove it
events.Add(docEvent );
docEvent.DocumentOpened += (document)=>{
Console.Write("document was opened!");
};
// you may add more events:
var commandEvent = dte.Events.CommandEvents;
events.Add(commandEvent );
commandEvent.AfterExecute+= etc...
}