[IT168 技术文档]摘要: 本文主要针对企业中使用Office 自动化来构建利用Office 产品内置的功能和特性的自定义解决方案所产生的一些复杂情况,提供实际可行的解决方案。
开发人员可以使用Office 自动化来完成利用Office 产品内置的功能和特性的自定义解决方案。 但是,由于这种使用方式并不是Microsoft所推荐以及支持的,如果要通过服务器端代码(例如,Active Server Pages (ASP)、DCOM 或 NT Service)进行“自动化”,就会发生一些不可预知的情况。
本文主要针对开发人员可能会面对的这些复杂情况,提供可以提高性能的“自动化”备选方案,并提出在必须要进行服务器端“自动化”的情况下配置 Office 的方法。
1. 使用服务器端 Office 自动化时出现的问题
在使用服务器端Office 自动化解决方案的时候应当了解到Office的表现会因为环境的不同而表现出主要的五大问题。要成功运行您的代码,就需要解决这些问题,而且需要尽可能减少它们的影响。在构建自己的应用程序时,要仔细考虑这几个问题,因为没有任何一种解决方案能全部解决所有这些问题,不同的设计要求您优先考虑不同的元素。
1. 用户身份:Office 应用程序在由“自动化”启动运行时会假定存在一个用户身份。它们根据用户注册表配置单元中的设置为启动应用程序的用户初始化工具栏、菜单、选项、打印机和一些加载项。许多服务会在没有用户配置文件的帐户下运行,因此,Office 可能无法在启动时进行正确的初始化,进而返回一个有关“CreateObject”或“CoCreateInstance”的错误。即使能够在没有用户配置文件的情况下启动 Office 应用程序,其他功能也可能无法正常工作。
2. 与桌面的交互性:Office 应用程序假定它们在某个交互式桌面下运行,在有些情况下,可能需要让用户看到它们以便某些“自动化”功能正常运行。如果需要一个未指定的参数才能完成某项功能,Office 会用一个模式对话框提示用户,询问用户要进行什么操作。非交互式桌面上的模式对话框是无法取消的,这就导致该线程无限期地停止响应。
3. 重入和可伸缩性:服务器端组件需要是具有较高可重入性的多线程 COM 组件,这些组件在有多个客户端时开销最少而吞吐量较高。Office 应用程序在几乎所有方面都正好相反。它们是非重入的“自动化”服务器,是为给一个客户端提供多种多样但占用资源较多的功能而设计的。它们作为服务器端解决方案可能会限制能够并发运行的实例的数量,而且,如果它们是在多客户端环境中配置的,还可能导致争用的情况。
4. 复原性和稳定性:Office 2000、Office XP 和 Office 2003 使用 Microsoft Windows 安装程序 (MSI) 技术,以使最终用户在进行安装和自行修复时更加容易。MSI 推出了“首次使用时安装”的概念,允许在运行时动态安装或配置功能。在服务器端环境中,这会既降低性能,又增加出现要求用户同意安装或提供相应安装盘的对话框的可能性。此外,在服务器端运行时,Office 的稳定性通常无法得到保障,因为它尚未为这样使用而进行设计或测试。在网络服务器上使用 Office 作为服务组件可能会降低这台计算机的稳定性,进而降低您的网络作为一个整体的稳定性。
5. 服务器端安全性:Office 应用程序从来都不是为在服务器端使用而准备的,因此,请不要考虑分布式组件所面临的安全性问题。Office 不对传入的请求进行身份验证,而且不会保护您免受无意中从服务器端代码中运行宏或启动另一台可能会运行宏的服务器的损害。
除了上述这些需要特别注意的问题外,我们在进行服务器端自动化时可能会遇到下列常见错误之一:
• “CreateObject/CoCreateInstance”返回以下运行时错误消息之一,而且无法启动进行自动化。
在 Microsoft Visual Basic (VB) 或 ASP 中:
• 消息 1: Run-time error '429': ActiveX component cannot create object
• 消息 2: Run-time error '70': Permission denied
在 Microsoft Visual C 或 Visual C++ 中:
• 消息 1: CO_E_SERVER_EXEC_FAILURE (0x80080005): Server execution failed
• 消息 2: E_ACCESSDENIED (0x80070005): Access denied
出现这些错误是因为服务器端代码在没有用户配置文件的情况下运行,或者为启动上下文指定的用户身份没有正确的 DCOM 权限。
• 打开 Office 文档会导致下列错误之一:
• 消息 1: Run-time error '5981' (0x800A175D): Could not open macro storage
• 消息 2: Run-time error '1004': Method '~' of object '~' failed
通常,出现这种情况是由于无法初始化 VBA,而无法初始化的原因是权限不足或缺少 VBA 组件注册,当用户从没有用户配置文件的帐户中运行代码(问题 1)并且用户标记不包含“交互式 SID”(问题 2)时,这两种原因都很常见。
• “CreateObject/CoCreateInstance”挂起并无法完成,或者需要很长时间才能返回。在有些服务器上,创建很快完成,但 Windows (NT) 事件日志中出现 1004 错误。
• 运行多个请求或压力测试可能导致在创建或终止 Office 应用程序时代码失败、挂起或崩溃。一旦出现这种情况,进程会在内存中保持运行状态且无法终止,或者正在自动化的应用程序的所有实例都从该点开始失败。
2. 主要解决方案
如果决定继续在服务器端进行“Office 自动化”,我们需要解决前面列出的许多问题才能在这种环境中成功运行。由于大多数问题都是与配置相关的,所以无法给出一套让“Office 自动化”在所有系统的所有情况下都能在服务器端正常运行的步骤。有些配置设置可能会与其他选项冲突,每种方法都各有利弊。这可能需要不断试验,才会找到最适用于自己环境的方案。
在程序准备就绪可以部署之后,一定要在服务器上正确配置 Office,以便运行合适的用户上下文。Office 需要用户配置文件,并且必须确保它在加载时有一个配置文件才能成功实现自动化。在服务器端环境中工作时,主要使用如下两种方法:
• 将“自动化”启动的 Office 应用程序所有实例都配置以“交互式”用户的身份运行。
• 将“自动化”启动的 Office 应用程的所有实例都配置为以某个特定用户的身份运行。
将 Office 应用程序配置为在交互式用户帐户下运行
这种方法可以使 Office 同时获得特定桌面的身份和可交互性,它是调试时的非常好的选择。为了成功运行,这种方法确实会要求交互式用户保持登录状态,所以,它可能不适用于某些情况。
在交互式用户帐户下设置 Office 自动化服务器:
1. 以管理员身份登录到计算机,并使用完整安装来安装Office。
2. 启动要自动运行的 Office 应用程序。这会强制该应用程序进行自我注册。
3. 运行该应用程序后,请按 Alt+F11 以加载 Microsoft Visual Basic for Applications (VBA) 编辑器。这会强制 VBA 进行初始化。
4. 关闭应用程序,包括 VBA。
5. 单击开始,单击运行,然后键入 DCOMCNFG。选择要自动运行的Office应用程序。单击属性打开此应用程序的属性对话框。
6. 单击安全选项卡。验证使用默认的访问权限和使用默认的启动权限已选中。
7. 单击标识选项卡,然后选择交互式用户。
8. 单击确定,关闭属性对话框并返回主应用程序列表对话框。
9. 在 DCOM 配置对话框中,单击默认安全性选项卡。
10. 单击访问权限的编辑默认值。验证访问权限中是否列出下列用户,如果没有列出,则添加这些用户:
SYSTEM
INTERACTIVE
Everyone
Administrators
IUSR_<machinename>
IWAM_<machinename>
11. 确保允许每个用户访问,然后单击确定。
12. 单击启动权限的编辑默认值。验证启动权限中是否列出下列用户,如果没有列出,则添加第10中的那些用户:
13. 确保允许每个用户访问,然后单击确定。
14. 单击确定关闭 DCOMCNFG。
15. 启动 REGEDIT,然后验证对于要自动运行的 Office 应用程序,是否存在下列注册表项和字符串值:
Microsoft Access 2000/2002:
注册表项:HKEY_CLASSES_ROOT\AppID\MSACCESS.EXE
AppID:{73A4C9C1-D68D-11D0-98BF-00A0C90DC8D9}
Microsoft Access 97:
注册表项:HKEY_CLASSES_ROOT\AppID\MSACCESS.EXE
AppID:{8CC49940-3146-11CF-97A1-00AA00424A9F}
Microsoft Excel 97/2000/2002:
注册表项:HKEY_CLASSES_ROOT\AppID\EXCEL.EXE
AppID:{00020812-0000-0000-C000-000000000046}
Microsoft Word 97/2000/2002:
注册表项:HKEY_CLASSES_ROOT\AppID\WINWORD.EXE
AppID:{00020906-0000-0000-C000-000000000046}
如果这些注册表项不存在,则可以在系统中创建它们。
16. 重新启动系统。这是必需的。
将 Office 应用程序配置为在特定用户帐户下运行
这种方法会指定一个特定用户,但不允许交互性。Office 会在一个不可见的桌面上的新 WinStation 中以被指定用户的身份启动。这种方法需要进行一些其他配置,以确保加载用户注册表配置单元,因为在默认情况下 COM/DCOM 不会做这一步。该设置对于系统来说是全局性的,所以它可能会与其他程序冲突
要在特定用户帐户下设置 Office 自动化服务器:
1. 以管理员身份登录到计算机,然后创建一个可自动运行 Office 的新用户帐户。在本例中,此帐户命名为 OfficeAutomationUser。创建此用户帐户的密码,并选择“永不过期”以便不必更改密码。
2. 将 OfficeAutomationUser 帐户添加到“管理员”组。
3. 以 OfficeAutomationUser 身份登录到计算机,并使用完整安装来安装Office。4. 启动要自动运行的 Office 应用程序。这会强制该应用程序进行自我注册。
5. 运行该应用程序后,请按 Alt+F11 以加载 Microsoft Visual Basic for Applications (VBA) 编辑器。这会强制 VBA 进行初始化。
6. 关闭应用程序,包括 VBA。
7. 单击“开始”,单击“运行”,然后键入 DCOMCNFG。选择要自动运行的应用程序。单击“属性”打开此应用程序的属性对话框。
8. 单击“安全”选项卡。验证“使用默认的访问权限”和“使用默认的启动权限”已选中。
9. 单击“标识”选项卡。选择“下列用户”,并键入 OfficeAutomationUser 的用户名和密码。
10. 单击“确定”,关闭属性对话框并返回主应用程序列表对话框。
11. 在“DCOM 配置”对话框中,单击“默认安全性”选项卡。
12. 单击访问权限的“编辑默认值”。验证访问权限中是否列出下列用户,如果没有列出,则添加这些用户:
SYSTEM
INTERACTIVE
Everyone
Administrators
OfficeAutomationUser
IUSR_<machinename>
IWAM_<machinename>
13. 确保允许每个用户访问,然后单击“确定”。
14. 单击启动权限的“编辑默认值”。验证启动权限中是否列出下列用户,如果没有列出,则添加第12中的用户:
15. 确保允许每个用户访问,然后单击“确定”。
16. 单击“确定”关闭 DCOMCNFG。
17. 启动 REGEDIT,然后验证对于要自动运行的 Office 应用程序,是否存在下列注册表项和字符串值:
Microsoft Access 2000/2002/2003:
注册表项:HKEY_CLASSES_ROOT\AppID\MSACCESS.EXE
AppID:{73A4C9C1-D68D-11D0-98BF-00A0C90DC8D9}
Microsoft Access 97:
注册表项:HKEY_CLASSES_ROOT\AppID\MSACCESS.EXE
AppID:{8CC49940-3146-11CF-97A1-00AA00424A9F}
Microsoft Excel 97/2000/2002/2003:
注册表项:HKEY_CLASSES_ROOT\AppID\EXCEL.EXE
AppID:{00020812-0000-0000-C000-000000000046}
Microsoft Word 97/2000/2002/2003:
注册表项:HKEY_CLASSES_ROOT\AppID\WINWORD.EXE
AppID:{00020906-0000-0000-C000-000000000046}
如果这些注册表项不存在,则可以在系统中创建它们
18. 要避免注册表冲突,请安装并运行 NT 服务。设置服务的标识以作为 OfficeAutomationUser 运行,并选择“自动”作为启动类型。
19. 重新启动系统。
3. 小结
本文主要对自动化Office应用的方案中所经常遇到的问题,提供了一些通常可以尝试解决的方法。我们需要评估上述哪种方法适合自身的需要,以及如何才能最好地部署解决方案。此处提供的信息不保证能够解决所有客户端的所有问题。建议最好在部署之前彻底地进行测试。
同时,除了此处列出的问题或消息之外,还可能出现一些其他问题和消息,但它们通常作为前面列出的五个问题的结果出现。为了解决这几种错误,开发人员应该将 Office 的操作环境配置为模拟客户端状态,或者从任何服务器端代码中删除 Office 应用程序并改为使用更稳定的组件(或客户端“自动化”)。