2013-01-04 49 views
12

我用「添加爲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; 
} 

但無論我這樣做,我的處理程序永遠不會被執行!

我是瞎了?我必須做其他事情來註冊這些處理程序或爲什麼它不工作?

+0

我有同樣的問題....有時。有時候我部署時,事件會起作用,有時候不會。沒有意義。 – Earlz

+1

對於BuildEvents:此API支持.NET Framework基礎結構,不能在代碼中直接使用。 僅限Microsoft內部使用。 – jessehouwing

+0

也許_applicationObject正在垃圾收集? –

回答

19

好像你是垃圾收集器的受害者。請參閱: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

這似乎並非如此。默認情況下,該加載項嚮導將讓這個所示在類級別創建'_applicationObject',而不是作爲一個局部變量 – Earlz

+0

不僅僅是_applicationObject,但你需要在strore一流水平的BuildEvents,SelectionEvents和DocumentEvents太。 – jessehouwing

+0

@jessehouwing我用DocumentEvents測試了這個。沒有幫助。 –

1

如果您在調試器看的applicationObject你會看到它的一個COM對象,但xxxEvents類不是 (如果你不能得到的代碼上的OnConnection突破,則可能你的插件沒有被加載,當你調試時,檢查工具菜單)

COM中的事件由另一個方向由服務器(VS)調用來觸發它們的另一個COM接口(在這種情況下是多個)處理。

雖然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