服务器端自动化Office组件失败的原因及解决办法

时间:2024-03-12 09:27:02

 问题描述:    
        在Windowos 2003下安装了最新的补丁SP1,导致我们的系统一个旧功能报错。此功能是导入Excel,也就是客户可以在Excel文件中把数据做好,然后利用此导入功能把数据导入到系统中。我们的做法是先把客户选择的Excel文件上传到Web服务器指定的位置,然后在服务器端打开Excel文件把数据转成数据流写到客户端展示,客户端提供修改和保存的功能。这是一个常功能,可是现在确不能用了。此代码结构是asp+vb。
出错代码j是在VB的CreateObject("Excel.Application")这一句。错误好像是无法创建对象。
问题分析:
        刚开始以为是权限的问题,也就是认为在win2003的sp1对office组件的安全性作了进一步的限制,在尝试了多次放开权限后终于发现如果把WEB服务器上IIS的默认用户改为本地的Administrator用户就可以了。其实之前也出现过同样的问题,那时候是把操作Excel的类放到一个Com+组件中,安装sp1后也是不能创建对象,同样是更改此组件的Com+关于权限方面的属性才可以的。后来认为这是一个普通功能,不应该置于Com+环境中,以免影响性能,所以写了一个单独的注册组件来操作Excel,里面只有一个类。问题是找到了解决办法,但是我们的领导和客户都不能接受把iis的用户权限无止境的放大到最大化,其实也是有道理的,假若是你你也不愿意,对吧!于是找到microsoft的工程师了解为什么win2003SP1要对office组件作进一步的限制,既然如此,那怎么样解决操作office组件的问题。我们得到的答案是完全不同的。以下是Microsoft解释:
  Microsoft 目前建议不要从任何无人值守的、非交互式客户端应用程序或组件(包括 ASP、DCOM 和 NT Service)中进行 Microsoft Office 应用程序的“自动化”,也不为此提供支持,因为 Office 在这种环境中运行时可能会出现不稳定的现象并且/或者会死锁。
.......
除了这些比较大的问题以外,许多客户还发现在不修改其 Office 默认安装的情况下,尝试进行服务器端自动化时可能遇到下列常见错误之一: • CreateObject/CoCreateInstance 返回以下运行时错误信息之一,而且无法为“自动化”启动:在 Microsoft Visual Basic (VB) 或 ASP 中:
Run-time error \'429\':ActiveX component cannot create object
- 或 - Run-time error \'70\':Permission denied
   以上描述来源来微软中国客户支持中的文章;INFO:服务器端 Office 自动化应考虑的因素

看来不是SP1的原因,属于Office设计的问题.但确实在window2003SP1之前是没有问题的,并且在window2003SP1下的C/S程序调用同事的组件也没有任何问题。虽然此文章写的很清楚,但还让我不自然的想到与权限有关的问题。从文章中的描述可以知道,所有服务器端的自动化CreateObject("XXX.Application")XXX代表Office组件名,都是不可行的。与调用语言无关,不论是VB还是.Net。分析我们的代码,调用此CreateObject的目的是枚举当前Excel文件中所有Sheet的名称,供用户选择将操作那一表单。接下来就用ADO来读取当前表单的数据。

解决办法:
          从文章中我们可以看到微软给出了多种指导解决办法,结合我们系统的要求,其实我认为是所有类似问题最优的方法是用ADO或ADO。NET来代替CreateObject。其实一个Excel就相当于一个数据库文件,通过ADO我们能获取数据中所有的表名和某个或某此表的数据,所以我们也能通过ADO来获取Excel文件所有的表单并且能获取某个表单的数据。接下来的问题就很简单了。
如果不清楚可以看看:EXCEL读取与写入数据的最佳方案(个人认为)     选择自 WindowsBoy 的 Blog

总结:
       其实问题很简单,只是我把它复杂化了,或许是我们大多数据程序员的通病。其实用ADO来操作Excel文件我们早就会,可我没有用它,认为CreateObject也不错,却不清楚这背后的密秘。