如何检查 COM 对象是否仍然存在

How to check if a COM object still exists

我基本了解托管 RCW 对象如何在 .NET 中包装 COM 对象。我的问题是当 COM 对象不复存在时会发生什么。我知道 RCW 对象会增加引用计数,因此只要 RCW 对象还活着,就不应释放 COM 对象。但是,如果从用户的角度来看,COM 对象 已删除 怎么办?

尝试表明 COM 对象在访问任何 属性 时抛出 COMException,错误代码为 0x80004005,表示 对象不存在

但我想知道:这是一种可靠且万无一失的方法吗? COM 对象真的会和 RCW 对象一起存在吗?还是 Office 可能会将其从内存中删除?在那种情况下,使用悬挂引用不是很危险吗?有没有更好的方法?

Is this a reliable and fail-safe approach?

是的,是的。没有更好的方法来处理 COM 对象。当然,在代码中延迟 COM 对象时,您需要处理异常。此外,我建议处理可以告诉您发生了什么的事件 - 特定对象是否被删除等。

Will the COM object really stay around with the RCW object or may Office remove it from memory?

Office 可以从内存中删除对象。我建议保留对象 ID 而不是保留直接引用。

In that case, isn't it dangerous to use the dangling reference and is there a better approach?

没有更好的方法。请参阅我以前的答案以获取更多信息.. >

你所做的事情本身就是有风险的。在用户与 Office 程序交互时使用自动化是很棘手的,您必须仔细编码。特定的 COM 对象不会被删除,它们是引用计数的,并且您持有对它的引用。但是当用户从文档中删除它时,内存中只剩下一个对象,它当然不再是文档的一部分了。

尝试取消引用该对象的成员确实很可能会失败。 Office 程序本身可能已删除该对象保留的任何内部引用。你得到了一个非常糟糕的异常,这也不罕见,0x80004005 是 E_FAIL,"Unspecified error"。很难说是错误,只是老师对报错质量的打分。

理想情况下,您会收到一个通知您删除对象引用的事件。很难获得,Office 应用程序并不那么健谈。最好的做法是 保留参考文献,但在需要时随时找回。如果那不切实际,那么您将 try/catch-em-all 作为最终的后备 hack。

您可以像这样使用 try-catch 组合:

try
{               
    ProcessString(s);
}
catch (Exception e)
{
    Console.WriteLine("{0} Exception caught.", e);
}