简体   繁体   English

运行时可调用包装器(RCW)范围 - 进程或应用程序域?

[英]Runtime callable wrapper (RCW) scope - process or application domain?

What is the scope of Runtime Callable Wrapper (RCW), when referencing unmanaged COM objects? 在引用非托管COM对象时,Runtime Callable Wrapper(RCW)的范围是什么? According to the docs: 根据文件:

The runtime creates exactly one RCW for each COM object, regardless of the number of references that exist on that object. 无论该对象上存在多少引用,运行时都会为每个COM对象创建一个RCW。

If I had to "guess" - this explanation should mean "one per process", but is it really? 如果我不得不“猜测” - 这个解释应该意味着“每个过程一个”,但它真的吗? Any additional documentation will be very welcome. 我们非常欢迎任何其他文件。

My application runs in its own application domain (it is Outlook addin), and I would like to know what happens if I use Marshal.ReleaseComObject(x) in a loop until it's count reaches 0 (as recommended). 我的应用程序在自己的应用程序域(它是Outlook插件)中运行,我想知道如果我在循环中使用Marshal.ReleaseComObject(x)直到它的计数达到0(如推荐)会发生什么。 Will it release references from other addins (running in other application domain in the same Outlook process)? 它会从其他插件中释放引用(在同一个Outlook进程中的其他应用程序域中运行)吗?

EDIT: Perfect - now the confusion is even bigger. 编辑:完美 - 现在混乱更大。 Based on the 2 answers (from Lette and Ilya) we have 2 different answers. 基于2个答案(来自Lette和Ilya),我们有2个不同的答案。 The official MSDN doc says per process (for ver. 2.0+), but it is missing this sentence for ver. 官方MSDN文档说每个进程(版本2.0+),但它缺少ver的这句话 1.1 of the doc . 1.1的文件

In the same time, in Mason Bendixen's article, it says it's per appdomain. 与此同时,在Mason Bendixen的文章中,它表示它是每个appdomain。

As his article is old (April 2007), I have send him an email asking for clarification, but if someone else has to add something, please do. 由于他的文章已经过时(2007年4月),我已经给他发了一封电子邮件要求澄清,但是如果其他人必须添加一些东西,请做。

Thanks 谢谢

In managed, we have a per app domain cache mapping canonical IUnknowns back to RCWs. 在托管中,我们有一个每个应用程序域缓存映射规范IUnknowns回到RCWs。 When an IUnknown enters the system (through a marshal call, through activation, as a return parameter from a method call, etc.), we check the cache to see if an RCW already exists for the COM object. 当IUnknown进入系统时(通过编组调用,通过激活,作为方法调用的返回参数等),我们检查缓存以查看COM对象是否已存在RCW。 If a mapping exists, a reference to the existing RCW is returned. 如果存在映射,则返回对现有RCW的引用。 Otherwise a new RCW is created and a cache mapping is added. 否则,将创建新的RCW并添加缓存映射。

from Mason's Blog 来自梅森的博客

The Mason Bendixen blog article that Ilya cites is correct: the RCW is scoped to the AppDomain, not to the process. Ilya引用的Mason Bendixen博客文章是正确的:RCW的范围是AppDomain,而不是进程。 I can only guess that the Runtime Callable Wrapper (MSDN 2.0) article was speaking "casually". 我只能猜测Runtime Callable Wrapper(MSDN 2.0)文章是“随便”说的。 That article is not necessarily incorrect in the general sense, because it is most typical to execute using only a single AppDomain, but that sentence is not technically accurate. 该文章在一般意义上不一定是不正确的,因为最典型的是仅使用单个AppDomain执行,但该句子在技术上并不准确。

As to your specific question: 至于你的具体问题:

"I would like to know what happens if I use Marshal.ReleaseComObject(x) in a loop until it's count reaches 0 (as recommended). Will it release references from other addins (running in other application domain in the same Outlook process)??" “我想知道如果我在循环中使用Marshal.ReleaseComObject(x)直到它的计数达到0(如推荐的话)会发生什么。它会从其他插件中释放引用(在同一个Outlook进程中的其他应用程序域中运行)吗? ?”

The answer to this depends on how you set up your add-in. 答案取决于您设置加载项的方式。 In general, if you do not take precautions, then the answer is yes, it would impact the references in other add-ins operating from within the same AppDomain. 通常,如果您不采取预防措施,那么答案是肯定的,它会影响在同一AppDomain中运行的其他加载项中的引用。 But since you state that you are running from a separate AppDomain, then, no, it would not. 但既然你说你是从一个单独的AppDomain运行,那么,不,它不会。

There is a COM Shim Wizard Version 2.3.1 that you can use to isolate your add-in. 有一个COM Shim Wizard版本2.3.1 ,您可以使用它来隔离您的加载项。 The documentation for the COM Shim Wizard can be found here: Isolating Microsoft Office Extensions with the COM Shim Wizard Version 2.3.1 . 可以在此处找到COM Shim向导的文档: 使用COM Shim Wizard版本2.3.1隔离Microsoft Office Extensions

The COM Shim Wizard uses reflection to build a customized COM front-end loader that loads your add-in assembly within a separate AppDomain. COM Shim向导使用反射来构建自定义的COM前端加载程序,该加载程序在单独的AppDomain中加载加载项程序集。 This creates safety in two respects: 这在两个方面创造了安全性:

(1) By using a separate, customized COM entry point, your add-in is correctly identified separately by Microsoft Office from all other add-ins. (1)通过使用单独的自定义COM入口点,Microsoft Office可以从所有其他加载项中单独正确识别加载项。 Otherwise, by default, all add-ins share the same default mscoree.dll loader. 否则,默认情况下,所有加载项共享相同的默认mscoree.dll加载程序。 The problem with sharing the same loader is that if any add-in has a crash, then mscoree.dll will be identified by Microsoft Office as the source of the problem and will not load it automatically the next time. 共享相同加载程序的问题是,如果任何加载项发生崩溃,则mscoree.dll将被Microsoft Office识别为问题的根源,并且下次不会自动加载它。 You can turn it on again manually, but your add-in would not load automatically the next time due to a problem in someone else's add-in! 您可以手动重新打开它,但由于其他人的加载项出现问题,您的加载项下次不会自动加载!

(2) By loading your assembly within a separate AppDomain, the runtime callable wrappers (RCWs) are isolated from the other add-ins that are loaded into the same process. (2)通过在单独的AppDomain中加载程序集,运行时可调用包装器(RCW)与加载到同一进程中的其他加载项隔离。 In this case, if you call Marshal.ReleaseComObject(object) or Marshal.FinalReleaseComObject(object) then you would not be impacting anyone else's add-ins. 在这种情况下,如果你调用Marshal.ReleaseComObject(object)或Marshal.FinalReleaseComObject(object),那么你就不会影响其他人的加载项。 More importantly, if any of those other add-ins make such calls, then your add-in would be protected from being corrupted. 更重要的是,如果任何其他加载项进行此类调用,则可以保护您的加载项免受损坏。 :-) :-)

The downside to using the COM Shim Wizard is that by operating out of a separate AppDomain there is extra marshalling overhead. 使用COM Shim向导的缺点是,通过操作单独的AppDomain,会产生额外的编组开销。 I don't believe that this should be noticeable for a Microsoft Outlook add-in. 我不相信这对于Microsoft Outlook加载项应该是显而易见的。 It can be a factor, however, for some intensive routines that have lots of calls to the object model, such as can sometimes be the case for a Microsoft Excel add-in. 但是,对于某些对对象模型进行大量调用的密集例程,这可能是一个因素,例如有时可能是Microsoft Excel加载项的情况。

You stated that you are already running your add-in from a separate AppDomain. 您声明已经从单独的AppDomain运行加载项。 If this is true, then you are already isolated from Marshal.ReleaseComObject(object) and Marshal.FinalReleaseComObject(object) calls with respect to other AppDomains. 如果这是真的,那么您已经与Marshal.ReleaseComObject(对象)和Marshal.FinalReleaseComObject(对象)相对于其他AppDomain进行了隔离。 (I am curious as to how you are doing this, by the way... Are you explicitly creating your own AppDomain? The default add-in template in Visual Studio does not run in separate AppDomain and loads using the mscoree.dll.) (顺便说一下,我很好奇你是如何做到这一点的......你明确地创建了自己的AppDomain吗?Visual Studio中的默认加载项模板不在单独的AppDomain中运行, 而是使用mscoree.dll加载。)

If you are creating your own AppDomain, your code is isolated, but its identity might not be separate from other add-ins, however, as your add-in would still be sharing the default mscoree.dll loader, unless you utilized some other means to address this. 如果您正在创建自己的AppDomain,则代码是隔离的,但其身份可能与其他加载项不同,但是,因为您的加载项仍将共享默认的mscoree.dll加载器,除非您使用其他方法解决这个问题。

I hope this helps... 我希望这有帮助...

According to the same docs: 根据相同的文档:

The runtime maintains a single RCW per process for each object. 运行时为每个对象维护每个进程一个RCW。

I think we can safely assume that object = instance , so if the addins/AppDomains doesn't hold references to the same instance, the call to ReleaseComObject won't release references to instances created elsewhere. 我认为我们可以安全地假设object = instance ,因此如果addins / AppDomains不保存对同一实例的引用,则对ReleaseComObject的调用将不会释放对其他地方创建的实例的引用。

Edit: The wording of the docs may be wrong, as stated elsewhere . 编辑: 如其他地方所述,文档的措辞可能是错误的。 If so, since your add-in is running in a separate AppDomain, you're in luck. 如果是这样,因为你的加载项是在一个单独的AppDomain中运行的,所以你很幸运。 Even if the different add-ins reference the same instance (eg a Message object in Outlook), ReleaseComObject called in your AppDomain will not cause RCWs in other AppDomains to lose the reference to that instance. 即使不同的加载项引用相同的实例(如Outlook中的邮件对象), ReleaseComObject在你的AppDomain叫不会导致的RCW在其他的AppDomain失去参照该实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Interop和RCW(运行时可调用包装器)有什么区别? - What is the difference between an Interop and a RCW (Runtime Callable Wrapper)? RCW(运行时可调用包装程序)是在.net中调用非托管com对象的唯一方法吗? - Is RCW(Runtime Callable Wrapper) the only way of calling an unmanaged com object in .net? 终结器线程的范围是什么 - 每个应用程序域或每个进程? - What is the scope of finalizer thread - per application domain or per process? 应用程序池vs应用程序域vs工作进程 - application pool vs application domain vs worker process COM Callable Wrapper和.NET对象生存期 - COM Callable Wrapper and .NET object lifetime ComDefaultInterface 对 COM 可调用包装器有什么用途吗? - Is there any purpose of ComDefaultInterface for a COM Callable Wrapper? 具有多步骤过程的应用程序层不使用域层是否可以? - Is It Okay for an Application Layer with a multi-step process to not use the domain layer 如何诊断COM可调用包装器对象创建失败? - How to diagnose COM-callable wrapper object creation failure? .NET COM Callable Wrapper 如何生成 IID? - How does the .NET COM Callable Wrapper generate IIDs? 如何解决.NET COM可调用包装DLL的注册/使用问题? - How to troubleshoot registration/usage of a .NET COM Callable Wrapper DLL?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM