2013-01-04 17 views
12

ho usato il "Add-in per Visual Studio" procedura guidata per creare un nuovo progetto componente aggiuntivo e adesso, sto cercando di aggiungere alcuni gestori di eventi:Add-In eventi non vengono mai eseguiti

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; 
} 

Ma qualunque Lo faccio, i miei gestori non vengono mai eseguiti!

Sono cieco? Devo fare qualcos'altro per registrare questi gestori o perché non funziona?

+0

Ho lo stesso problema .... a volte. A volte, quando eseguo il deployment, gli eventi funzioneranno ... ea volte no. Non ha senso. – Earlz

+1

Per BuildEvents: questa API supporta l'infrastruttura .NET Framework e non è progettata per essere utilizzata direttamente dal codice. Solo per uso interno di Microsoft. – jessehouwing

+0

Forse _applicationObject è in corso di garbage collection? –

risposta

19

Sembra che tu sia una vittima del Garbage Collector. Vedi: 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

Questo non sembra essere il caso. Per impostazione predefinita, la procedura guidata aggiunta farà sì che il ''applicationObject' mostrato sia creato a livello di classe, non come variabile locale – Earlz

+0

Non solo _applicationObject, ma è necessario strorizzare BuildEvents, SelectionEvents e DocumentEvents a livello di classe pure. – jessehouwing

+0

@jessehouwing Ho provato questo con DocumentEvents. Non ha aiutato –

1

Se guardate applicationObject nel debugger vedrete la sua un oggetto COM, ma le classi non sono xxxEvents (Se non è possibile ottenere il codice di rompere l'OnConnection, poi eventualmente il tuo addin non viene caricato durante il debug, controlla il menu degli strumenti)

Gli eventi in COM vengono gestiti da un'interfaccia COM separata (molti in questo caso) nell'altra direzione che il server (VS) chiama per attivarli .

Sebbene gli oggetti COM abbiano un concetto di assembly tipizzato simile agli assembly CLR, sono codice non gestito internamente, pertanto non può contenere le radici negli oggetti gestiti.

Quindi, sebbene sia possibile collegare un delegato a un evento COM in un modo che assomiglia esattamente a un evento CLR nativo, l'evento viene agganciato a un RCW (runtime callable wrapper). Esiste un riferimento COM dal server all'interfaccia com RCW, ma senza una radice CLR, infine, RCW viene eliminato e scarica l'interfaccia com, dopo di che non si affondano eventi.

non sono sicuro, ma penso che questo di solito funziona quando si consuma un oggetto COM singolo con un'associazione diretta per le sue interfacce di eventi per cui il suo forse a causa di come l'interfaccia COM DTE è strutturata ...

Comunque come altri hanno già detto che è necessario qualsiasi tipo di riferimento gestito alle classi BuildEvents, SelectionEvents e DocumentEvents dall'oggetto app per risolverlo. Più istanze di VS caricano istanze separate del componente aggiuntivo in modo da poter semplicemente aggiungere un elenco di riferimenti ad oggetti statici e impostarli in OnConnect.

Subscription to DTE events doesn't seem to work - Events don't get called

http://msdn.microsoft.com/en-us/library/k639e386.aspx