无法访问Excel文件

12

我正在开发一个Windows服务来生成报告。这个报告有一个模板,该模板是在Excel文件中准备的。然后将此文件复制到输出文件夹。

在开发过程中,我像控制台应用程序一样启动了服务,并且在访问这个文件时没有任何问题。

之后我准备了一个服务安装程序。该服务已安装在Local System帐户下。因此,这个Excel模板文件被标记为content,并连同可执行文件一起复制到安装目录中。

但是当服务启动时,Excel似乎无法访问这个文件。服务安装在c:\Program Files (x86)\Our Company\Service Name\中。目标操作系统是Windows Server 2008。在测试过程中,我使用Windows 7并遇到了相同的问题。

我使用以下代码来访问Excel:

using Excel = Microsoft.Office.Interop.Excel;    
//...
Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
//the following line throws an exception
Excel.Workbook xlWorkBook = xlApp.Workbooks.Open(@"path"); 

我还尝试将Excel模板文件复制到某个临时目录(服务有写入权限-已测试),并尝试从那里打开它,但没有成功(而在控制台应用程序中此变量也能正常工作)。

错误信息如下:

Microsoft Office Excel无法访问文件/路径/。可能有几个原因:

1. The file name or path does not exist.
2. The file is being used by another program.
3. The workbook you are trying to save has the same name as a currently open workbook.
我该如何让Windows服务访问这个Excel模板文件?或者有其他替代方案吗?

如果您将服务使用管理员帐户(例如您自己的帐户)而不是本地系统,它是否可以工作? - Shadow The Spring Wizard
@ShadowWizard 让我试试看。 - horgh
不,我想不出你做错了什么。可能是与Interop本身有关的问题,我会继续研究它。 - Shadow The Spring Wizard
Excel期望从交互式桌面运行。当从服务中调用时,您正在尝试在Session 0中运行它。而Session 0没有交互式桌面。 - David Heffernan
你应该停止使用LocalSystem。现在已经是2013年了!在20世纪就是一种不好的做法。而且UAC在服务中毫无意义。 - David Heffernan
显示剩余6条评论
3个回答

17
为了在用户服务下使用本地系统帐户安全运行Office应用程序(如Excel等),您必须了解两个重要的事项: 1)在Windows Server 2008/2008 R2中,您必须手动创建两个文件夹:        C:\ Windows \ system32 \ config \ systemprofile \ desktop
       C:\ Windows \ SysWow64 \ config \ systemprofile \ desktop(仅适用于x64版本)    如果没有这些文件夹,您将无法从Local SystemAccount正确运行Office应用程序。
2)如果您的服务未配置桌面交互,则第一次启动Office应用程序(例如Excel)会在用户凭据对话框上冻结-在此模式下您无法看到此窗口-要解决此问题,请启用桌面交互,在服务运行后切换到Office窗口并手动输入凭据。
其他信息there(使用谷歌翻译阅读)。

2
我在使用Windows 7时遇到了这个问题。添加路径C:\Windows\system32\config\systemprofile\desktop解决了这个问题。非常感谢您的帖子。 - Christian O'Reilly
创建两个文件夹解决了我在Windows 8.1上的问题。 - CAA
尽管上面有警告,但我认为如果你正在执行特定任务(已经过测试的任务,而不是以一般方式使用它),并且某些任务只有 Excel 才能完成(没有第三方库可以像 Excel 一样高效地操作大文件),它可以可靠地运行。 - dudeNumber4
谢谢,你让我的一天变得美好了,我已经在解决这个问题上忙碌了两天。 - ChupChapCharli
曾经与 Microsoft Windows Server 2022 Datacenter 工作过。 - anilsathyan7
显示剩余3条评论

9

有一篇详细的微软知识库文章,标题为考虑 Office 服务器端自动化的问题。以下是一些关键摘录:

  • 用户身份:当应用程序运行时,即使是自动化启动应用程序,Office 应用程序也会假定一个用户身份。这些应用程序尝试根据启动应用程序的用户的用户注册表中的设置来初始化工具栏、菜单、选项、打印机和某些加载项。许多服务在没有用户配置文件的帐户下运行(例如 SYSTEM 帐户或 IWAM_[servername] 帐户)。因此,在启动时 Office 可能无法正确初始化。在这种情况下,Office 在 CreateObject 函数或 CoCreateInstance 函数上返回错误。即使可以启动 Office 应用程序,如果不存在用户配置文件,则其他函数可能无法正常工作。

  • 与桌面的交互性:Office 应用程序假定它们在交互式桌面下运行。在某些情况下,应用程序可能需要可见才能使某些自动化函数正常工作。如果发生意外错误,或者需要指定的参数以完成函数,则 Office 设计为使用模态对话框提示用户询问用户想要做什么。非交互式桌面上的模态对话框无法关闭。因此,该线程将无限期地停止响应(挂起)。尽管某些编码实践可以帮助减少此问题的可能性,但这些实践无法完全防止该问题。仅此事实就使得从服务器端环境运行 Office 应用程序变得不安全且不受支持。

显然,正如评论中指出的那样,使用SYSTEM帐户是一个错误。您需要在具有用户配置文件的帐户下运行服务。

但即使您修复了这个问题,其他要点也会让您无法继续。Office应用程序确实假定它们在交互式桌面下运行。我的建议是放弃尝试从服务自动化Office。使用像Aspose这样的库。或在交互式桌面上运行进程。


David,非常感谢你提供的这个优秀链接和所有信息。现在我得考虑一下其他选择。 - horgh

0

我刚刚遇到了同样的问题。

我创建了一个 .bat 文件,其中调用了 .exe 文件。

最后,我从任务计划程序操作中调用了 .bat 文件。

它完美地运行了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接