2013-01-04 1 views
12

je le « Add-In pour Visual Studio » Assistant pour créer un nouveau projet Addin et maintenant, je suis en train d'ajouter des gestionnaires d'événements:Add-In événements ne sont jamais exécutés

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

Mais quel que soit Je fais, mes gestionnaires ne sont jamais exécutés!

Est-ce que je suis aveugle? Dois-je faire autre chose pour enregistrer ces gestionnaires ou pourquoi cela ne fonctionne-t-il pas?

+0

J'ai le même problème .... parfois. Parfois, quand je me déploie, les événements fonctionnent ... et parfois non. Ça n'a aucun sens. – Earlz

+1

Pour BuildEvents: Cette API prend en charge l'infrastructure .NET Framework et n'est pas destinée à être utilisée directement à partir de votre code. Utilisation interne de Microsoft uniquement. – jessehouwing

+0

Peut-être que _applicationObject est en cours de collecte? –

Répondre

19

Semble que vous êtes victime du récupérateur de place. Voir: 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

Cela ne semble pas être le cas. Par défaut, l'assistant de complément fera en sorte que l'objet '_applicationObject' affiché soit créé au niveau de la classe, pas en tant que variable locale. – Earlz

+0

Non seulement le _applicationObject, mais vous devez strorer les BuildEvents, SelectionEvents et DocumentEvents au niveau de la classe aussi. – jessehouwing

+0

@jessehouwing J'ai testé cela avec DocumentEvents. N'a pas aidé. –

1

Si vous regardez applicationObject dans le débogueur vous verrez son un objet COM, mais les classes xxxEvents ne sont pas (Si vous ne pouvez pas obtenir le code pour briser le OnConnection, alors peut-être votre addin n'est pas chargé lorsque vous déboguez, vérifiez le menu outils)

Les événements dans COM sont gérés par une interface COM séparée (plusieurs dans ce cas) dans l'autre direction que le serveur (VS) appelle pour les déclencher. .

Bien que les objets COM aient un concept d'assemblage typé similaire à celui des assemblys CLR, ils sont internes au code non géré, de sorte que ne peut pas contenir de racines dans les objets gérés. Par conséquent, bien que vous puissiez raccorder un délégué à un événement COM d'une manière qui ressemble exactement à un événement CLR natif, votre événement est accroché à un RCW (wrapper callable à l'exécution). Il existe une référence COM du serveur à l'interface RCW com, mais sans une racine CLR, le RCW finit par être éliminé ce qui décharge l'interface com, après quoi vous ne coulerez aucun événement.

Je ne suis pas sûr, mais je pense que cela fonctionne normalement lorsque vous consommez un seul objet COM avec une association directe à ses interfaces d'événements de sorte que son peut-être en raison de la façon dont l'interface COM DTE est structuré ...

Quoi qu'il en soit Comme d'autres l'ont dit, vous avez juste besoin de n'importe quelle sorte de référence gérée aux classes BuildEvents, SelectionEvents et DocumentEvents de l'objet d'application pour le réparer. Plusieurs instances de VS chargent des instances séparées de l'add-in. Vous pouvez donc simplement ajouter une liste de références d'objets statiques et les définir dans OnConnect.

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

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

Questions connexes