为什么 Word Interop 抱怨 "class not registered" 错误,而 Excel interop 却没有?

Why is Word Interop complaining of a "class not registered" error, when Excel interop doesn't?

我们有一个应用程序已经存在了一段时间,它使用 Excel Interop 库。该项目引用 Microsoft.Office.Interop.Excel 并指向 Visual Studio 中的默认路径。

最近有人要求我在这个基于Word 互操作的项目中添加一些功能。这一切在开发中都很顺利。我在同一位置 (C:\Program Files (x86)\Microsoft Visual Studio 12.0\Visual Studio Tools for Office\PIA\Office15 添加了对 Word interop dll 的引用。

服务器上同时安装了 Word 和 Excel。但是,虽然 Excel 互操作继续运行,但尝试使用 Word 函数会引发此错误:

System.Runtime.InteropServices.COMException (0x80040154): Retrieving the COM class factory for component with CLSID {000209FF-0000-0000-C000-000000000046} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).

对该错误的引用表明这是由于 32/64 位冲突造成的,我觉得这很令人惊讶。 dll 是 32 位的,项目构建目标是 "Any CPU"。此外,它毫无怨言地运行 32 位 Excel 互操作。

据我所知,Excel 上的 Word 都没有在服务器的注册表中安装互操作 dll。

这里有什么?这真的归结为架构不匹配吗?如果不能,为什么我的应用程序能够使用已安装的 Excel 互操作而不是 Word 互操作?

互操作文件不应在服务器上注册,它们不是 COM 服务器。相反,我建议重新安装 Office 应用程序(修复它们)以确保在您尝试自动化它们时创建并存在 COM 服务器所需的所有 windows 注册表项。

否则,您遇到了一个众所周知的问题...Microsoft 目前不建议也不支持从任何无人值守的非交互式客户端应用程序或组件(包括 ASP、ASP.NET、DCOM 和 NT 服务),因为当 Office 在此环境中 运行 时,Office 可能表现出不稳定的行为 and/or 死锁。

如果您正在构建 运行 在服务器端上下文中的解决方案,您应该尝试使用已针对无人值守执行安全处理的组件。或者,您应该尝试找到至少允许 运行 客户端部分代码的替代方案。如果您从服务器端解决方案使用 Office 应用程序,该应用程序将缺少许多 运行 成功所必需的功能。此外,您将承担整体解决方案稳定性的风险。在 Considerations for server-side Automation of Office 文章中阅读更多相关信息。

作为一种可能的解决方法,您可以考虑使用 Open XML SDK 或任何其他专为服务器端执行而设计的第三方组件。

这是一个难题,因为微软不支持该方案。参考:Considerations for the server-side automation of office .

尝试更改属性中 "Embed Interop types" 的设置以引用 Office 库。这使得代码独立于任何特定应用程序版本的 PIA,并且可以解决服务器端安装的任何问题。

PInvoke (GetType.InvokeMember) 还使解决方案独立于应用程序版本,并且可以在整个过程中使用。但是,这是更多的工作,因为您没有 Intellisense。

此嵌入互操作类型存在一些已知问题,因为在嵌入式互操作类型如何嵌入信息(不同于 PIA 的构建方式)方面存在一些 "hiccups"。在这种情况下,可能需要使用 PInvoke 来解决问题 methods/properties。这两种方法可以结合使用。