Question

Quelle est la portée de Runtime Callable Wrapper (RCW) lors de la référence à des objets COM non gérés? Selon la documentation:

  

Le moteur d'exécution crée exactement un RCW.   pour chaque objet COM, quelle que soit la   nombre de références existantes sur   cet objet.

Si je devais "deviner" - cette explication devrait signifier "un par processus", mais est-ce vraiment? Toute documentation supplémentaire sera la bienvenue.

Mon application s'exécute dans son propre domaine d'application (il s'agit du complément Outlook) et j'aimerais savoir ce qui se passe si j'utilise Marshal.ReleaseComObject (x) dans une boucle jusqu'à ce que son nombre atteigne 0 (comme recommandé). Publiera-t-il des références d'autres add-ins (s'exécutant dans un autre domaine d'application dans le même processus Outlook)?

EDIT: Parfait - maintenant la confusion est encore plus grande. Sur la base des 2 réponses (de Lette et Ilya), nous avons 2 réponses différentes. Le doc MSDN officiel dit par processus (pour version 2.0+), mais il manque cette phrase pour ver. 1.1 de la doc .

Dans le même temps, dans l'article de Mason Bendixen, on dit que c'est par domaine.

Son article étant ancien (avril 2007), je lui ai envoyé un courrier électronique pour lui demander des éclaircissements, mais si quelqu'un d'autre devait ajouter quelque chose, faites-le.

Merci

Était-ce utile?

La solution

  

Dans la gestion, nous avons un domaine par application.   cache   cartographie IUnknowns canonique retour à   RCW. Quand un IUnknown entre dans la   système (par un appel de marshal,   par activation, comme retour   paramètre à partir d'un appel de méthode, etc.),   nous vérifions le cache pour voir si un RCW   existe déjà pour l'objet COM. Si   une cartographie existe, une référence à la   RCW existant est retourné. Sinon un   nouveau RCW est créé et un mappage de cache   est ajouté.

de Blog de Mason

Autres conseils

L'article de blog Mason Bendixen cité par Ilya est correct: le RCW est associé à AppDomain et non au processus. Je peux seulement deviner que le Wrapper Callable d'exécution (MSDN 2.0) L'article parlait "avec désinvolture". Cet article n’est pas nécessairement incorrect au sens général, car il est très courant d’exécuter en utilisant un seul AppDomain, mais cette phrase n’est pas techniquement exacte.

En ce qui concerne votre question spécifique:

  

"J'aimerais savoir ce qui se passe si je   utilisez Marshal.ReleaseComObject (x) dans un   boucle jusqu’à ce que son compte atteigne 0 (comme   conseillé). Va-t-il libérer   références d'autres addins   (s'exécutant dans un autre domaine d'application   dans le même processus Outlook) ?? "

La réponse à cette question dépend de la manière dont vous avez configuré votre complément. En général, si vous ne prenez pas de précautions, la réponse est oui, cela aurait un impact sur les références des autres compléments opérant à partir du même AppDomain. Mais puisque vous déclarez que vous exécutez à partir d'un AppDomain séparé, alors non, ce ne serait pas le cas.

Il existe un Shim COM Assistant Version 2.3.1 que vous pouvez utiliser pour isoler votre complément. La documentation relative à l'Assistant COM Shim est disponible à l'adresse suivante: Isolation des extensions Microsoft Office à l'aide de la Assistant COM Shim version 2.3.1 .

L’assistant COM Shim utilise la réflexion pour créer un chargeur frontal COM personnalisé qui charge votre assembly de complément dans un AppDomain séparé. Cela crée une sécurité à deux égards:

(1) En utilisant un point d’entrée COM personnalisé et séparé, votre complément est correctement identifié séparément par Microsoft Office par tous les autres compléments. Sinon, par défaut, tous les compléments partagent le même chargeur par défaut mscoree.dll. Le problème avec le partage du même chargeur est que si l'un des compléments est bloqué, alors mscoree.dll sera identifié par Microsoft Office comme source du problème et ne le chargera pas automatiquement la prochaine fois. Vous pouvez le réactiver manuellement, mais votre complément ne se chargera pas automatiquement la prochaine fois en raison d'un problème rencontré dans le complément de quelqu'un d'autre!

(2) En chargeant votre assemblage dans un domaine AppDomain distinct, les wrappers appelables à l'exécution (RCW) sont isolés des autres compléments chargés dans le même processus. Dans ce cas, si vous appelez Marshal.ReleaseComObject (objet) ou Marshal.FinalReleaseComObject (objet), vous n'auriez aucun impact sur les compléments de quelqu'un d'autre. Plus important encore, si l'un de ces compléments passait de tels appels, votre complément serait protégé contre la corruption. : -)

L’utilisation de l’assistant COM Shim Wizard présente l’inconvénient que, si vous utilisez un AppDomain séparé, vous bénéficiez d’une surcharge de travail en marshalling. Je ne crois pas que cela devrait être perceptible pour un complément Microsoft Outlook. Toutefois, cela peut être un facteur pour certaines routines intensives faisant appel au modèle objet, comme cela peut parfois être le cas pour un complément Microsoft Excel.

Vous avez indiqué que vous exécutez déjà votre complément à partir d'un AppDomain séparé. Si cela est vrai, vous êtes déjà isolé des appels Marshal.ReleaseComObject (objet) et Marshal.FinalReleaseComObject (objet) par rapport à d'autres AppDomains. (Je suis curieux de savoir comment vous faites cela, soit dit en passant ... Créez-vous explicitement votre propre AppDomain? Le modèle de complément par défaut dans Visual Studio ne s'exécute pas dans un AppDomain séparé et se charge en utilisant le mscoree.dll.)

Si vous créez votre propre AppDomain, votre code est isolé, mais son identité peut ne pas être distincte des autres compléments. Toutefois, votre complément partageant toujours le chargeur par défaut mscoree.dll, à moins que vous n'ayez utilisé un autre moyen de remédier à cela.

J'espère que cela vous aidera ...

Selon les mêmes documents:

  

Le moteur d'exécution maintient un seul RCW par processus pour chaque objet.

Je pense que nous pouvons supposer en toute sécurité que objet = instance . Par conséquent, si les addins / AppDomains ne contiennent pas de références à la même instance, l'appel à ReleaseComObject ne publiera pas de références aux instances créées ailleurs.

Modifier: le libellé de la documentation est peut-être incorrect. comme indiqué ailleurs . Si tel est le cas, votre complément fonctionnant dans un domaine AppDomain distinct, vous avez de la chance. Même si les différents compléments font référence à la même instance (par exemple, un objet Message dans Outlook), ReleaseComObject appelé dans votre AppDomain n'entraînera pas la perte de la référence à cette instance dans les RCWs des autres AppDomains.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top