问题描述
最近写网页程序,服务器需要操作Excel,但是网页端发送请求后服务器不能创建Excel,出现如下错误:
检索 COM 类工厂中 CLSID 为 {00024500-0000-0000-C000-000000000046} 的组件失败,原因是出现以下错误: 80070005 拒绝访问。
抛出错误的代码为:
ExApp = new Excel.Application { DisplayAlerts = false };
注:上述错误是在发布网页后才会出现,在发布网页之前直接在VS里运行是没有问题的。
解决方法
网上很多帖子说是DCOM问题,需要在"DCOM配置"中找到"Microsoft Excel 应用程序",属性里添加NETWORK SERVICE和IIS_IUSRS用户,标识设为交互式用户,然而这并没有解决我的问题!
在上面设置尝试之后,下面的设置成功的解决了我的问题:
1、DCOM→Microsoft Excel 应用程序→属性→标识→启动用户
2、IIS→应用程序池→选择自己的网站→高级设置→标识→自定义账户→输入当前登录账户的用户名和密码
IIS设置
经过以上2步设置后,后台成功调用Excel!
原因分析
以下纯属个人见解,错误之处还望各位留言指正,欢迎讨论。
一般这种问题都会涉及到DCOM的设置,究其原因,还是程序的权限问题,就像错误提示的那样,容易出现类似错误的场景还包括OPC server和OPC client之间的通讯(见我之前的帖子OPC的坑)。
在B/S框架下,服务器后台的程序一般没有用户界面的,或者我们把它理解为后台程序是以Windows服务的方式工作的,这时候后台程序访问的资源也应该是服务方式的,或者说不应该以交互式方式访问其他资源(对应我的情况就是Excel)。那么这时我们就应该在服务器的DCOM里把Excel的标识改为启动用户(这时服务器后台程序就相当于OPC server,如果OPC server是以Windows服务方式工作的,那么该OPC server的DCOM也应该是启动用户,而不是交互式用户)。相应的,在IIS里,我们网站的标识应该改为当前登录的账户。
所以,完整的流程是:
当前端发送请求后,服务器端按照IIS中应用程序池里设置的标识账户登录(相当于启动用户),进行后端的程序响应,调用相应的资源(如以启动用户方式访问Excel),完成后端响应,前端接收响应结果。在这个过程中,要保证从前到后的访问方式是一致的,或者是兼容的,例如启动用户只能访问以启动用户方式工作的其他程序,不能访问以交互式方式工作的其他程序。
补充说明
如果遇到“Microsoft Office Excel 不能访问文件”的错误,可以尝试
在C:\Windows\System32\config\systemprofile和C:\Windows\SysWOW64\config\systemprofile目录下创建名为Desktop的文件夹
其他参考
1、# Microsoft.Office.Interop.Excel 放到B/S客户端失败问题 检索 COM 类工厂中 CLSID 为 {00024500-0000-0000-C000-000000000046} 的组件失败,原因是出现以下错误: 80070005 拒绝访问。
2、检索 COM 类工厂中 CLSID 为 {00024500-0000-0000-C000-000000000046} 的组件失败的解决方案
网友评论