基于 Windows Server 2008 x64 的 Excel 2007 自动化

25
我知道微软支持文档中指出不支持无界面自动化 Office 产品。似乎Windows Server 2008 x64 和Excel 2007执行了这个规定。
我在一个NT服务(本地系统帐户)的OnStart方法中运行以下代码。它所做的就是通过Excel自动化方式工作,就像在Console应用程序中运行相同的代码一样。
提供的代码有两部分。第一部分启动Excel,创建一个新工作簿并将其保存到给定文件名中。第二部分启动一个新的Excel实例并打开给定的文件。打开操作以此异常结束:
“服务无法启动。System.Runtime.InteropServices.COMException (0x800A03EC):Microsoft Office Excel无法访问文件'c:\temp\test.xls'。有几个可能的原因:”
• 文件名或路径不存在。 • 文件正在被另一个程序使用。 • 您要保存的工作簿与当前打开的工作簿具有相同的名称。 为什么自动化的Excel能够启动并将文件写入磁盘,但在被要求“只是”打开现有文件时失败了?
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US");
// launch excel and create/save a new work book
Microsoft.Office.Interop.Excel.ApplicationClass excel = new       Microsoft.Office.Interop.Excel.ApplicationClass();
excel.UserLibraryPath, excel.Interactive));
//            
string filename = "c:\\temp\\test.xls";
if(System.IO.File.Exists(filename)) System.IO.File.Delete(filename);
//
excel.Workbooks.Add(System.Reflection.Missing.Value);
excel.Save(filename);
excel.Quit();
excel = null;
// lauch new instance of excel and open saved file
excel = new Microsoft.Office.Interop.Excel.ApplicationClass();
try
{
    Microsoft.Office.Interop.Excel.Workbook book = excel.Workbooks.Open(filename,
                System.Reflection.Missing.Value,
                System.Reflection.Missing.Value,
                System.Reflection.Missing.Value,
                System.Reflection.Missing.Value,
                System.Reflection.Missing.Value,
                true,
                System.Reflection.Missing.Value,
                System.Reflection.Missing.Value,
                false,
                false,
                System.Reflection.Missing.Value,
                false,
                System.Reflection.Missing.Value,
                System.Reflection.Missing.Value);
     book.Close(false, System.Reflection.Missing.Value, System.Reflection.Missing.Value);
      book = null;
  }
  finally
  {
      excel.Quit();
      excel = null;
  }
  //
  GC.Collect();

请注意:同样的代码在部署到 Windows Server 2003 R2 x64 和 Excel 2007 的操作环境下也可以完美运行。 - Chris Richner
-1 旨在帮助新读者尝试从服务器进程进行Office自动化。 - John Saunders
@John Saunders。好的,接下来的要求怎么办:在不使用自动化的情况下,在xls文件内运行“更新”宏?只是好奇(并不是说这样的设计一开始就是个好主意,但用户就是用户……) - Vinzz
@Vinzz:如果有其他无法满足的需求,你会怎么做:说实话。 - John Saunders
@John Saunder:唉,在这种特殊情况下,它可以(而且已经)满足了。但确实,试图说服别人另一个解决方案是更好的想法。 - Vinzz
@Vinzz:你的意思是Excel在不支持的情况下运行了吗?如果需求没有明确说明“支持”,那我想这就是“满足”了。 - John Saunders
5个回答

31

解决方案非常简单。msdn论坛的帖子可以在这里找到。

长话短说,我在这里发布解决方案,感谢H Ogawa提供的帮助。

解决方案如下:

・Windows 2008 Server x64:

请创建以下文件夹。

C:\Windows\SysWOW64\config\systemprofile\Desktop

・Windows 2008 Server x86:

请创建以下文件夹。

C:\Windows\System32\config\systemprofile\Desktop

...而不是使用dcomcnfg.exe。

这个操作解决了我的系统中的Office自动化问题。

在systemprofile文件夹中似乎需要一个Desktop文件夹才能打开Excel文件。

它从Windows2008中消失了。Windows2003有这个文件夹,因此我认为这可能是导致这个错误的原因。


2
哇,就这样?我也遇到了这个问题,我以为是因为 Excel 在 Session 0 中运行。我使用 .Net 远程处理在已登录 Session 1 的用户下运行 Excel... - wm_eddie
1
你和H Ogawa都非常厉害。我也在研究 Session 0 的情况,但似乎是一个完全无关紧要的问题。 - Jeroen Ritmeijer
2
+1 对于最简单的解决方案和最难以解决的错误,点赞。 - Dayton Brown
我发布了一个相关问题,关于如何让它在非系统用户账户下工作。http://stackoverflow.com/questions/5226473/excel-2007-automation-on-top-of-a-windows-server-2008-x64-non-system-user - Suraj
@Chris - 你能找到为什么需要创建这个文件夹的解释吗?虽然它解决了我的问题,但我想知道为什么需要这个文件夹。 - thiag0
显示剩余2条评论

7
同样如源中所述,您需要为桌面文件夹设置正确的权限。 这对我在Windows 2008-64位和Office 2010 32位上有效。
1. 创建目录 "C:\Windows\SysWOW64\config\systemprofile\Desktop"(64位Windows)或 "C:\Windows\System32\config\systemprofile\Desktop"(32位Windows)。
2. 为创建的文件夹分配用户 "Network Services (Service Réseau)"以下权限:
读取和执行、列出文件夹内容、读取。
John。

1
这是一个可怕的拼图中最后缺失的一块。谢谢! - Michael Paulukonis

2

我经常发现仅仅调用Quit()方法并不能释放资源。尝试添加以下代码:

System.Runtime.InteropServices.Marshal.ReleaseComObject(excel);

在 Quit() 语句和将其设置为 null 的代码之间。


谢谢,你猜怎么着,我删掉了代码的这一部分,以使示例尽可能简单。顺便说一下,ReleaseComObject返回一个整数,应该放在循环中。 - Chris Richner
2
如果您的程序退出,等待垃圾回收器也是一个好习惯:GC.Collect(); GC.WaitForPendingFinalizers(); - sonstabo

1

1
如果你正在使用Apache,你可能还需要遵循以下步骤才能使MS Word正常工作(除了其他答案中概述的所有内容):
下面是一个屏幕截图,显示了您需要打开的两个对话框: enter image description here 对于Apache:
服务->Apache->右键单击(属性)->登录选项卡
MS Word:
启动dcomcnfg.exe->控制台根目录->组件服务->计算机->我的电脑->DCOM配置->查找Microsoft应用程序->右键单击(属性)->标识选项卡
**如果找不到MS Word,请确保启动正确的DCOM配置(64位与32位),这取决于您安装的Office版本。
这里有两个选项,您可以将Apache设置为使用本地系统帐户并选中允许桌面交互的复选框。如果这样做,则需要将MS Word的身份设置为“交互式用户”。
否则,您需要将两个设置为相同的用户(最好是已登录的用户),如图片所示。

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