2011-08-30 53 views
0

在我的项目中,我需要在服务器端自动执行ExcelWord以供客户端使用。我在示例控制台应用程序中运行我的代码,并且都运行良好,但是在WCF服务中,出现了一些错误。在WCF服务中使用Office自动处理引发异常

我的代码如下所示:

var wordApp = new Word.Application(); 
wordApp.Visible = true; 
wordApp.Documents.Add(); 

wordApp.Selection.PasteSpecial(Link: true, DisplayAsIcon: true); //Throws exception 

var _excelApp = new Excel.Application(); 
_excelApp.Visible = true; 

_excelApp.Worksheets.Add(); //Throws exception 

,并且错误是:

System.Runtime.InteropServices.COMException了未处理的
用户代码
HELPLINK = wdmain11.chm# 24822
消息=指定的数据类型不可用。
源= Microsoft Word中
错误码= -2146822946
堆栈跟踪:
在Microsoft.Office.Interop.Word.Selection.PasteSpecial(对象&
IconIndex,对象&链接,对象&布局,对象& DisplayAsIcon,
对象&数据类型,对象& IconFileName,对象& IconLabel)
在OfficeApiPlugin.UsingOfficeApiService.DisplyWorksheet(WorksheetRow []
worksheetD ATA)
在SyncInvokeDisplyWorksheet(对象,对象[],对象[])
在System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(对象
例如,对象[]输入,对象[] &输出)
在系统.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc &
RPC)


System.Runtime.InteropServices.COMEx ception了未处理由用户
代码
消息从HRESULT =异常:0x800A03EC
源=的Microsoft.Office.Interop.Excel
错误码= -2146827284
堆栈跟踪:
在Microsoft.Office.Interop.Excel.ApplicationClass .get_Worksheets()
在OfficeApiPlugin.UsingOfficeApiService.DisplyWorksheet(WorksheetRow []
worksheetData)在C:\用户\ Mahdi7s \文件\的Visual Studio
2010 \项目\ OfficeApiPlugin \ OfficeApiPlugin \ UsingOfficeApiService.cs:线
在SyncInvokeDisplyWorksheet(对象,对象[],对象[])
在System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(对象
例如,对象[]输入,对象[] &输出)
在System.ServiceModel .Dispatcher.DispatchOperationRuntime。InvokeBegin(MessageRpc &
RPC)

我怎么能做到这一点没有这样的错误?

+0

你如何托管你的WCF服务? – Dyppl

+0

错误似乎表明Word和Excel应用程序未安装在您的服务器上。顺便说一句:我总是试图避免在服务器上使用COM互操作 - 尝试使用其他方法(如OpenXML接口)在服务器上创建Word或Excel文档,而无需安装**在你的服务器上的办公室.... –

+0

@Dyppl:我在一个wpf应用程序中托管我的服务。 – VirtualWorld

回答

0

我认为问题是剪贴板(这是吹起来的操作)需要使用STA COM线程。 WCF调用在MTA线程的线程池线程上执行。

使用Thread类打开自己的线程,并将其ApartmentState设置为ApartmentState.STA,然后从那里执行Office自动化。最简单的事情就是阻止你的WCF线程,直到自动化完成。

几件事情要注意的,但是:

  1. 如果你有大量的并发呼叫你将不得不每次创建STA线程的线程池,而不是旋转了新一轮上涨。
  2. 为了获得更高的吞吐量,您可能需要考虑使您的服务操作异步,并创建自定义的IAsyncResult,以指示何时完成自动化。这将允许WCF线程在自动化进程中被重用。
+0

感谢您的回答,理查德我试着在STA ApartmentState的另一个线程中运行我的代码,也改变了我的服务从多重到单一的并发行为,但我仍然得到了错误... – VirtualWorld