Using Office automation in a WCF service throws exceptions
In my project, I need to automate Excel and Word at the server side for use by clients. I ran my code in a sample console application and all works well, but inside of the WCF service, I got some errors.
My code looks like this:
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
And the errors are:
System.Runtime.InteropServices.COMException was unhandled by
user code HelpLink=wdmain11.chm#24822 Message=The specified data type is unavailable. Source=Microsoft Word ErrorCode=-2146822946 StackTrace: at Microsoft.Office.Interop.Word.Selection.PasteSpecial(Object& IconIndex, Object& Link, Object& Placement, Object& DisplayAsIcon, Object& DataType, Object& IconFileName, Object& IconLabel) at OfficeApiPlugin.UsingOfficeApiService.DisplyWorksheet(WorksheetRow[] worksheetData) at SyncInvokeDisplyWorksheet(Object , Object[] , Object[] ) at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs) at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
System.Runtime.InteropServices.COMException was unhandled by user
code Message=Exception from HRESULT: 0x800A03EC Source=Microsoft.Office.Interop.Excel ErrorCode=-2146827284 StackTrace: at Microsoft.Office.Interop.Excel.ApplicationClass.get_Worksheets() at OfficeApiPlugin.UsingOfficeApiService.DisplyWorksheet(WorksheetRow[] worksheetData) in C:\Users\Mahdi7s\Documents\Visual Studio 2010\Projects\OfficeApiPlugin\OfficeApiPlugin\UsingOfficeApiService.cs:line 29 开发者_开发知识库at SyncInvokeDisplyWorksheet(Object , Object[] , Object[] ) at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs) at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
How can I do this without this errors?
I think the problem is that the clipboard (which is the operation that is blowing up) requires the use of an STA COM thread. WCF calls are performed on threadpool threads which are MTA threads.
Spin up your own thread using the Thread class and set its ApartmentState to ApartmentState.STA and then perform your Office automation from there. The simplest thing then would be to block your WCF thread until the automation is complete.
A couple of things to be aware of, however:
- If you have a lot of concurrent calls you will have to create a threadpool of STA threads rather than spin a new one up each time.
- For higher throughput you may want to consider making your service operation asynchronous and creating a custom IAsyncResult that signals when the automation is complete. This will allow the WCF thread to be reused while the automation is in progress.
精彩评论