2011-02-28 21 views
8

我需要从我的.Net4应用程序自动执行Office文档(Word & Excel)。C#.Net4:正确配置(动态)COM对象

由于我不能强制用户使用特定的Office版本,因此我不使用interop程序集或tlbimp,因此如果未安装Office,则我的项目不会包含任何其他引用,也不会导致整个应用程序失败(功能将不可用)。

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

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

我担心如何妥善处理“应用程序”对象的时候我因为现在我有两个内部管理系统担心(COM引用计数和.Net引用跟踪)。理想情况下,我应该能够将动态应用程序对象封装到一次性封装类中,并确保在封装处置时,底层COM对象未被引用。

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

+0

可能的重复:http://stackoverflow.com/questions/2203968/how-to-access-microsoft-word-existing-instance-using-late-binding – 2011-02-28 10:40:19

+2

不一定,重复的候选人更多关于C#中COM的实例化方面,这个问题是关于处置的。 – 2011-02-28 10:43:21

+0

确保你处理了任何中介COM对象 - http://stackoverflow.com/a/158752/188926 – Dunc 2013-02-26 15:47:09

回答

7

我肯定会执行IDisposable并在其中调用Marshal.ReleaseComObject。确保你correctly implement the disposable pattern避免多次释放COM对象,并且比你应该进一步减少引用计数,但如果你只是要创建一个COM对象实例,这可能并不重要。过去我成功实施了这个模式,所以你肯定会朝着正确的方向前进。

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

+0

所以在你链接的例子中,我应该用Marshal.FreeHGlobal(nativeResource)替换Marshal.ReleaseComObject(app)?而已? – 2011-02-28 10:46:48

+0

你当然不需要if()块,并且managedResource的东西可能与你的用例无关,但是是的,它应该正确地清理你的COM参考。我建议不要将IDisposable包装器全部传递到代码中,以尽量减少系统的其余部分暴露给这个特定的IDisposable。 – 2011-02-28 10:49:30