我在这里面临一种情况,希望得到一些反馈或建议。我得到了一个作为服务运行的应用程序,具有特定的服务帐户(不是服务器上的管理员),并尝试打开 Excel 工作簿。
问题不在于初始应用程序,因为我可以使用下面的通用 C# 代码(嵌入在服务结构中)重现它:
try{
this._exApp = new Microsoft.Office.Interop.Excel.ApplicationClass();
this._exApp.Visible = false;
Log.Logger.Info("Opening workbook...");
Workbook workbook = this._exApp.Workbooks.Open(
thisFileName,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing
);
Log.Logger.Info("Workbook opened!");
//Do something with the result
Log.Logger.Info("Closing workbook...");
workbook.Close(false, thisFileName, null);
Marshal.ReleaseComObject(workbook);
this._exApp.Quit();
}
catch(Exception ex){
Log.Logger.Error(ex.Message);
}
(关于 *this._exApp* 和thisFileName没有什么特别之处,它们只是分别转换为 Microsoft.Office.Interop.Excel.Application,并作为带有要打开的文件路径的字符串。Log.Logger 是一个记录器类,使用log4net 让我看到问题发生的时间)
该服务作为服务帐户运行,该帐户是服务器上的用户,而不是管理员。它可以访问目标文件和服务器上的文件(作为读取访问)。该服务器是 Windows Server 2003 Standard Edition SP2(无法在 2008 R2 服务器上试用)。
我面临的问题是它只是在尝试打开工作簿时挂起,所以在跟踪我的最后一行是“正在打开工作簿......”,从未到达“工作簿打开”行。没有引发异常。
所以代码很简单,只是想打开一个excel工作簿。我已经做了一些调查,以下是我的发现:
- 我知道 Microsoft 不支持服务器端 Excel 自动化,但我已经获得了它的服务,并且对所使用的技术没有选择权。
- 我已配置所有组件服务/DCOM/Microsoft Excel 应用程序安全设置,以便服务帐户拥有所有可能的权限。
- 如果服务帐户是计算机上的本地管理员,则该服务可以正确完成工作。这不是真正的生产选项。
- 如果它尝试打开的文件是本地文件,则该服务可以正确地完成这项工作。不幸的是,我们尝试访问的文件位于远程文件服务器上,在这种情况下它不起作用。
- 上面的代码在远程文件上使用同一用户从命令行运行正常,但在作为服务运行时就不行了。
- 我已阅读有关C:\Windows\System32\config\systemprofile\Desktop错误的信息,但该文件夹存在。
- 使用服务帐户启动时,Excel 可以正确打开。
所以基本上,情况是 Workbooks.Open 方法在作为服务运行时、在非管理员的服务帐户下以及访问远程文件时挂起。
我将不胜感激有关此主题的任何意见或想法。
谢谢。
乔纳森
编辑:根据下面马特的解决方法,我们已经实现了远程文件的本地副本,所以我接受它作为答案,但我仍然对如何使其直接在远程文件上工作的任何建议感兴趣。