在WCF服务中使用Office自动化会引发异常

时间:2011-08-30 09:20:58

标签: wcf office-interop

在我的项目中,我需要在服务器端自动化ExcelWord以供客户端使用。我在一个示例控制台应用程序中运行我的代码,一切正常,但在WCF服务内部,我遇到了一些错误。

我的代码如下所示:

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
  Message =指定的数据类型不可用。
  来源= Microsoft Word
  ErrorCode = -2146822946
  StackTrace:
  在Microsoft.Office.Interop.Word.Selection.PasteSpecial(Object&
  IconIndex,Object& Link,Object&放置,对象& DisplayAsIcon,
  对象和放大器; DataType,Object& IconFileName,Object& IconLabel)
  在OfficeApiPlugin.UsingOfficeApiService.DisplyWorksheet(WorksheetRow []
  worksheetData)
  在SyncInvokeDisplyWorksheet(Object,Object [],Object [])
  在System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(对象
  实例,对象[]输入,对象[]&输出)
  在System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&
  rpc)


  

用户未处理System.Runtime.InteropServices.COMException   代码
  消息=来自HRESULT的异常:0x800A03EC
  Source = Microsoft.Office.Interop.Excel
  ErrorCode = -2146827284
  StackTrace:
  在Microsoft.Office.Interop.Excel.ApplicationClass.get_Worksheets()
  在OfficeApiPlugin.UsingOfficeApiService.DisplyWorksheet(WorksheetRow []
  C:\ Users \ Mahdi7s \ Documents \ Visual Studio中的worksheetData)   2010 \ Projects \ OfficeApiPlugin \ OfficeApiPlugin \ UsingOfficeApiService.cs:line
  29
  在SyncInvokeDisplyWorksheet(Object,Object [],Object [])
  在System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(对象
  实例,对象[]输入,对象[]&输出)
  在System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&
  rpc)

如果没有这个错误,我怎么能这样做?

1 个答案:

答案 0 :(得分:0)

我认为问题在于剪贴板(正在爆炸的操作)需要使用STA COM线程。 WCF调用是在作为MTA线程的线程池线程上执行的。

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

然而,有几点需要注意:

  1. 如果您有很多并发调用,则必须创建一个STA线程的线程池,而不是每次都重新启动一个新线程。
  2. 为了获得更高的吞吐量,您可能需要考虑使服务操作异步并创建自定义IAsyncResult,以便在自动化完成时发出信号。这将允许在自动化进行过程中重用WCF线程。