在C#中正确处理COM互操作对象,尤其是MS Office应用程序

我正在开发一个依赖于多个Microsoft Office产品的应用程序,包括Access,Excel,Word,PowerPoint和Outlook等。 在对互操作进行研究时,我发现从VS2010和.NET 4开始,我们感谢不再需要经历PIA的噩梦。

此外,我一直在阅读很多关于妥善处理物品的文章,最明智的就是这个 。

然而,该文章已有5年历史,关于AFAIK主题的权威出版物并不多。 以下是上述链接中的代码示例:

' Cleanup: GC.Collect() GC.WaitForPendingFinalizers() GC.Collect() GC.WaitForPendingFinalizers() Marshal.FinalReleaseComObject(worksheet) oWB.Close(SaveChanges:=False) Marshal.FinalReleaseComObject(workbook) oApp.Quit() Marshal.FinalReleaseComObject(application) 

我想知道的是今天的标准,如果我希望在未来几年支持我的申请,我应该注意什么?

更新:一些可靠文章的链接将受到高度赞赏。 顺便说一句,这不是服务器端应用程序。 这将在计算机实验室中运行,我们让用户与我们实例化的办公产品进行交互。

发现它: 这篇由三部分组成的文章可能是最接近我期望找到的权威帐户的文章。

根据您通过互操作控制的Office版本以及服务器上发生的情况,是的,您可能需要做一些严肃的调整以摆脱其中一个Office应用程序的运行实例。 有不可预测的(和不必要的)对话框,例如,Word将在不是交互式时打开(没有一个Office应用程序特别适合无人值守的执行,因此建议即使使用最新版本也不安装它们服务器端使用)。

对于服务器案例,请考虑使用Aspose的堆栈而不是Office或其他替代方案。 在交互式的本地用例中,由于Office自动化服务器是特别糟糕的非托管对象,因此有时可能需要“额外的powershell查杀”。

在对象超出范围后,GC应自动处理对象。 如果您需要尽快发布它们,可以使用Marshal.ReleaseComObject http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.releasecomobject.aspx

如果要完全释放COM对象,尤其是在MS Office COM对象中,则强烈建议您释放必须使用的父对象内的子对象。

在您的示例中,我会说释放所有Cell,Range在释放单元格,范围或任何其他对象所属的工作表之前可能已使用的任何其他对象。