Office Interop does not work in Windows service

I have a very strange problem with Microsoft Office.

I have a shared library whose sole purpose is to open any type of Word document file (full path to the file ...) and save this open document as a PDF file.

The strange problem is that if I use this library from a Windows service, whenever it tries to open a Word document, I get zero ... otherwise, the document document never opens.

If I use the library from a WPF or Windows Form application, I never have any problems. I know that there are problems with thread processing (Single Thread Appartment), however I do not know how to fix this to work from a Windows service. :( :( :(

I would be grateful for any help! The error I get is: the following:

Exception message: {"The reference to the object is not installed in the instance of the object." } (refers to the word document). Internal exception: Null; HResult: -2147467261. Data: ListDictionaryInternal with 0 items; Stack Trace: in DocumentConverter.ToPdf (String currentWorkingFolderPath, String pathToDocumentToConvert) in c: \ Project Files ... \ DocumentConverter.cs: line 209

So here is the library function. This requires a Microsoft Office link created by Visual Studio Tools for Office.

private string ToPDF(string currentWorkingFolderPath, string pathToDocumentToConvert) { string temporaryPdfFolderPath = Path.GetFullPath(currentWorkingFolderPath + "\\pdf\\"); string temporaryPdfFilePath = Path.GetFullPath(temporaryPdfFolderPath + "\\pdffile.pdf"); if (!FileSystem.CreateDirectory(temporaryPdfFolderPath)) { return null; } try { Microsoft.Office.Interop.Word.Application wordApplication = new Microsoft.Office.Interop.Word.Application(); object objectMissing = System.Reflection.Missing.Value; wordApplication.Visible = false; wordApplication.ScreenUpdating = false; FileInfo wordFile = new FileInfo(pathToDocumentToConvert); Object fileName = (Object)wordFile.FullName; // This is where it breaks when called from windows service. Use the dummy value as a placeholder for optional arguments Document wordDocument = wordApplication.Documents.Open(ref fileName, ref objectMissing, true, ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing); object outputFileName = (object)temporaryPdfFilePath; object fileFormat = WdSaveFormat.wdFormatPDF ; // Save document into PDF Format wordDocument.SaveAs(ref outputFileName, ref fileFormat, ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing, ref objectMissing); // Close the Word document, but leave the Word application open. // doc has to be cast to type _Document so that it will find the // correct Close method. object saveChanges = WdSaveOptions.wdDoNotSaveChanges; ((_Document)wordDocument).Close(ref saveChanges, ref objectMissing, ref objectMissing); wordDocument = null; // word has to be cast to type _Application so that it will find // the correct Quit method. ((Microsoft.Office.Interop.Word._Application)wordApplication).Quit(ref objectMissing, ref objectMissing, ref objectMissing); wordApplication = null; } catch (Exception ex) { //logging code return null; } return temporaryPdfFilePath; } 
+4
source share
5 answers

Per @Sameer S in his post: Is Office 2003 interoperable on a Windows 2008 server ..?

Officially, Microsoft Office 2003 Interop is not supported on Microsoft Windows Server 2008.

But after many permutations and combinations with code and search, we came across one solution that works for our scenario.

The solution is to plug in the difference between how Windows 2003 and 2008 maintains its folder structure, since Office Interop depends on the desktop folder to open the file / save. In the 2003 system, there is a desktop folder under the system profile, missing in 2008.

So, when we create this folder in 2008 under the corresponding hierarchy, as indicated below; Interop office can save the file as needed. This desktop folder must be created under

C: \ Windows \ System32 \ Config \ systemprofile

and

C: \ Windows \ SysWOW64 \ Config \ systemprofile

Thanks guys..!

+21
source

Office Interop is not supported by MS in server-like scripts (e.g. ASP.NET or Windows Service or similar) - see http://support.microsoft.com/default.aspx?scid=kb;EN-US;q257757#kb2 !

To achieve what you want, you need a library:

+4
source

Does your Windows service have the "run interactively" option enabled? This may be unsuccessful because Word is trying to display a user interface, which for reasons that seem obvious, it cannot do.

Another possibility (and a fairly common problem in people) is that your Windows service runs under an account that does not have access rights to the file / folder that you are trying to transfer. WPF / Winforms, by contrast, runs under user credentials.

If this is not a problem, are there any errors? Check the Windows event log and / or add some logging to see if there are any errors that have been discreetly thrown.

EDIT: I looked at the MSDN documentation ( for Word Interop ), and it doesn't seem like VSTO is required. Can you try to do this with the pure word interop and see if it works? There is an example in this post

+1
source

Once these folders have been created:

C: \ Windows \ System32 \ Config \ systemprofile \ Desktop C: \ Windows \ SysWOW64 \ Config \ systemprofile \ Desktop

Verify that the schedule task is running with a profile with access to these folders.

+1
source

My automation application ASP.NET 2.0 works well in Windows Server 2008 64 bit after following the instructions from the link below. Hope this can help everyone.

http://emalvass.blogspot.com/2010/01/how-to-use-office-2007-automation-in.html

My sample program as below:

 Imports Microsoft.Office.Interop.Word Dim Result As Boolean = False Dim appWord As New Microsoft.Office.Interop.Word.Application Dim wordDocument As Microsoft.Office.Interop.Word.Document Try Dim oFile As New FileInfo(sPDFFile), sFilePath As String, sFileName As String, sFileNameArr() As String Dim sActualFileName As String sFileName = oFile.Name sFileNameArr = sFileName.Split(".") sActualFileName = sFileNameArr(0) sFilePath = oFile.DirectoryName & "\" & sActualFileName & ".pdf" wordDocument = appWord.Documents.Open(sPDFFile) wordDocument.ExportAsFixedFormat(sFilePath, WdExportFormat.wdExportFormatPDF) 'wordDocument.ExportAsFixedFormat(sFilePath, 17) Result = True oFile = Nothing Catch ex As COMException sErrMsg = ex.InnerException.ToString Result = False Finally wordDocument.Close() wordDocument = Nothing appWord.Application.Quit() appWord = Nothing End Try Return Result 
0
source

Source: https://habr.com/ru/post/1447296/


All Articles