Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Visual studio 订阅DTE活动不需要';似乎不起作用-事件不起作用';我没接到电话_Visual Studio_Visual Studio 2010_Vsx - Fatal编程技术网

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...

}