Ilya 引用的 Mason Bendixen 博客文章是正确的:RCW 的范围仅限于 AppDomain,而不是流程。我只能猜测Runtime Callable Wrapper (MSDN 2.0)文章是“随便”说的。那篇文章在一般意义上不一定是不正确的,因为最典型的是只使用单个 AppDomain 执行,但那句话在技术上并不准确。
至于你的具体问题:
“我想知道如果我在循环中使用 Marshal.ReleaseComObject(x) 直到它的计数达到 0(如推荐的那样)会发生什么。它会释放来自其他插件的引用(在同一 Outlook 进程中的其他应用程序域中运行)? ?”
答案取决于您如何设置加载项。一般来说,如果你不采取预防措施,那么答案是肯定的,它会影响在同一个 AppDomain 中运行的其他加载项中的引用。但是,既然您声明您是从一个单独的 AppDomain 运行的,那么,不,它不会。
有一个COM Shim 向导版本 2.3.1,您可以使用它来隔离您的加载项。COM Shim 向导的文档可以在这里找到:Isolating Microsoft Office Extensions with the COM Shim Wizard Version 2.3.1。
COM Shim 向导使用反射来构建一个自定义的 COM 前端加载器,该加载器将加载项程序集加载到单独的 AppDomain 中。这在两个方面创造了安全性:
(1) 通过使用单独的自定义 COM 入口点,Microsoft Office 可以正确地将您的加载项与所有其他加载项分开识别。否则,默认情况下,所有加载项都共享相同的默认 mscoree.dll 加载程序。共享同一个加载器的问题是,如果任何加载项发生崩溃,那么 mscoree.dll 将被 Microsoft Office 识别为问题的根源,并且下次不会自动加载它。您可以手动重新开启,但下次您的加载项不会因为别人加载项的问题而自动加载!
(2) 通过在单独的 AppDomain 中加载程序集,运行时可调用包装器 (RCW) 与加载到同一进程中的其他加载项隔离。在这种情况下,如果您调用 Marshal.ReleaseComObject(object) 或 Marshal.FinalReleaseComObject(object),那么您不会影响其他任何人的加载项。更重要的是,如果任何其他加载项进行此类调用,那么您的加载项将受到保护,不会被损坏。:-)
使用 COM Shim 向导的缺点是,在单独的 AppDomain 之外进行操作会产生额外的编组开销。我不认为这对于 Microsoft Outlook 加载项应该很明显。然而,对于一些对对象模型有大量调用的密集例程来说,这可能是一个因素,例如 Microsoft Excel 加载项有时就是这种情况。
您声明您已经从一个单独的 AppDomain 运行您的加载项。如果这是真的,那么您已经与其他 AppDomain 的 Marshal.ReleaseComObject(object) 和 Marshal.FinalReleaseComObject(object) 调用隔离开来。(顺便说一句,我很好奇你是如何做到这一点的......你是在明确创建自己的 AppDomain 吗?Visual Studio 中的默认加载项模板不在单独的 AppDomain 中运行,而是使用 mscoree.dll 加载。)
如果您正在创建自己的 AppDomain,则您的代码是隔离的,但它的身份可能不会与其他加载项分开,但是,因为您的加载项仍将共享默认的 mscoree.dll 加载程序,除非您使用其他方式来解决这个问题。
我希望这有帮助...