【问题标题】:C# .Net4: Properly disposing (dynamic) COM objectsC# .Net4:正确处理(动态)COM 对象
【发布时间】:2011-07-05 16:10:38
【问题描述】:

我需要从我的 .Net4 应用程序自动化办公文档(Word 和 Excel)。

由于我不能真正强制我的用户使用特定的 Office 版本,因此我不使用互操作程序集或 tlbimp,因此我的项目不包含任何额外的引用,如果未安装 Office,整个应用程序也不会失败(功能将不可用)。

相反,我询问系统哪个 COM 服务器可以处理“Word.Application”或“Excel.Application”:

dynamic app = Activator.CreateInstance(Type.GetTypeFromProgID("Word.Application"));
app.Foo();

我担心在完成“app”对象后如何正确处理它,因为现在我需要担心两个内部管理系统(COM 引用计数和 .Net 引用跟踪)。理想情况下,我应该能够将动态应用程序对象包装到一次性包装器类中,并确保在处理包装器时未引用底层 COM 对象。

编辑:另外我想知道当我完成它时如何正确地使 COM 对象“继续存在”,因为 Word 是在一个单独的进程中。我应该能够实例化 Word 应用程序,使其自动化,然后释放我的所有引用,但 Word 应用程序应该保持打开状态。

【问题讨论】:

标签: c# .net com com-interop


【解决方案1】:

我肯定会实现IDisposable 并在其中调用Marshal.ReleaseComObject。确保 correctly implement the disposable pattern 避免多次释放 COM 对象并进一步减少引用计数,尽管如果您只打算创建 COM 对象的一个​​实例,这可能无关紧要。我过去已经成功实现了这种模式,所以你肯定在朝着正确的方向前进。

认为即使您的应用程序中最后一个 COM 对象的引用计数为 0,Word 仍将保持打开状态,除非您明确要求它退出。 (Word.Application.Close()?)

【讨论】:

  • 所以在您链接的示例中,我应该将 Marshal.FreeHGlobal(nativeResource) 替换为 Marshal.ReleaseComObject(app)?就这样?
  • 您当然不需要 if() 块,并且 managedResource 的东西可能与您的用例无关,但是是的,否则应该正确清理您的 COM 引用。我建议不要在你的代码周围传递你的 IDisposable 包装器,以尽量减少系统的其余部分暴露于这个特定的 IDisposable。
猜你喜欢
  • 1970-01-01
  • 2012-12-15
  • 1970-01-01
  • 2011-12-13
  • 1970-01-01
  • 2015-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多