办公自动化#import有害吗?

问题描述:

http://code.msdn.microsoft.com/office/CppAutomateOutlook-55251528状态:办公自动化#import有害吗?

[...]这是非常强大,但通常不建议使用,因为 与 Microsoft Office应用程序一起使用时,经常会出现引用计数问题。 [...]

其中引用计数问题专门在这里是什么意思? 例如,它是否适用于特定示例?

同样作为例子,我只是想打开Outlook,创建约会,完成。

我想使用#import但这种声明让我感到害怕吧......

一个circular reference当你拿着引用对方,直接或间接地两个或多个对象发生。在COM中,这意味着循环链接的对象相互调用IUnknown::AddRef

如果使用Excel自动化,如果你的事件处理程序(汇)连接到该的Excell可能发生对象的采购活动(通过IConnectionPoint::Advise)。这样,您可能会保留对象,例如Application对象,而Application对象会保留对接收器的引用。

此问题不是专用于由VC++ #import指令生成的智能指针。这是关于如何在不再需要COM对象时关闭COM对象。您应该明确地断开您所做的所有连接(即,执行IConnectionPoint::Unadvise),并调用该对象可能公开的任何显式关闭API(例如,Workbook::CloseApplication::Quit)。那么你应该明确地释放你的参考(例如,在智能指针上调用workbookPtr.Release())。

这就是说,如果你不处理用Excel采购任何COM事件,你不应该担心太多,你可以创建一个循环引用的几率会很低。此外,Excel是一个进程外COM服务器,COM有一些garbage collection logic来管理进程外服务器的生命周期。但是,在应用程序仍处于打开状态时,Excel进程将保持活动状态,直到所有对其对象的引用都已释放,或调用了Application::Quit

+1

太好了,谢谢!我了解循环引用,但我不知道这是此陈述的原因。所以我可以放心地使用#import。 – divB

+1

@divB,除非你处理事件,否则执行“正常水平的预防措施”。否则,执行“高级别的预防措施”,并在完成特定的Excel对象时显式释放任何智能指针。 **如果您的应用程序终止,但Excel.exe仍然挂在进程列表中的时间超过几秒钟,那将是一个不好的迹象。** – Noseratio

这很无意义。借助#import编程Office进行互操作是样板和推荐的方式。它自动生成的智能指针类型明确用于为您自动完成引用计数,因此您不能忘记调用Release()。有一些尖锐的边缘,你必须明白什么是智能指针可以做和不做。

这是课程这是所有功能于一体代码框架背后的团队,否则相提并论。这些样本是由上海的一个支持团队创建的,最初被雇用来帮助MSDN论坛。这些人没有你在Redmond工作的微软程序员期望的那种凭证,他们的摘录也没有被审查。其中有些人是完全不适当的。如果您曾在MSDN论坛上提过问题,并看到他们发布的答案,那么您就明白我的意思了。

他们的Solution2.cpp示例通过IDispatch使用后期绑定。这绝对是与Office互操作的难题,当您编写代码时,您无论如何都得不到任何帮助。编写方法调用时,智能感知不能提供任何有用的信息,编译器也不能告诉您错过了一个参数或错误的参数类型。您的程序在运行时会因为不透明的错误代码而失败,如DISP_E_BADVARTYPE或DISP_E_BADPARAMCOUNT。 Release()调用必须明确地进行,当然这会使更容易错过。您使用智能指针时没有的问题,他们会给您自动完成和类型检查。您可以亲自看到Solution1.cpp具有多小和可读性。

诊断到Release()的未接来电很容易,您的程序完成但您仍然会看到Outlook.exe在任务管理器中运行。无论如何你会习惯于检查,当你调试你的程序,发现错误并停止程序来修正时,它也会发生。当然这也阻止了Release()被调用,所以Outlook将继续运行。你必须自己杀死它。

不要考虑用像C#或VB.NET这样的托管语言编写这种代码。如果您遇到问题,您将获得lot更多帮助,并且您会发现很多示例代码。垃圾收集器从不忘记发布呼叫。这样做有点慢。