Office Interop Does Not Work in Windows Service

19,622

Solution 1

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

Officially Microsoft Office 2003 Interop is not supported on Windows server 2008 by Microsoft.

But after a lot of permutations & combinations with the code and search, we came across one solution which works for our scenario.

The solution is to plug the difference between the way Windows 2003 and 2008 maintains its folder structure, because Office Interop depends on the desktop folder for file open/save intermediately. The 2003 system houses the desktop folder under systemprofile which is absent in 2008.

So when we create this folder on 2008 under the respective hierarchy as indicated below; the office Interop is able to save the file as required. This Desktop folder is required to be created under

C:\Windows\System32\config\systemprofile

AND

C:\Windows\SysWOW64\config\systemprofile

Thanks Guys..!

Solution 2

Once these folders have been created:

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

Make sure the schedule task is running with a profile having access to these folders.

Solution 3

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

You will need to use some library to achieve what you want:

Solution 4

Is your windows service have the 'run in interactive mode' option enabled? It may be failing because Word is attempting to display a UI, which for reasons which seem obvious, it cannot do.

Another possibility (and a pretty common problem people have) is that your Windows Service is running under an account that doesn't have permissions to access the file/folder you're attempting to pass to it. A WPF/Winforms program by contrast runs under the user's credentials.

If that is not the problem, are there any errors being thrown? Check the Windows Event Log and/or add some logging to see if there are some errors being silently thrown.

EDIT: I glanced through the MSDN documention (for Word Interop) and it doesn't appear that using VSTO is required. Can you attempt to do this using pure word interop and see if it works? This post has an example

Share:
19,622
bleepzter
Author by

bleepzter

The Master of Disaster, yours truly.

Updated on June 09, 2022

Comments

  • bleepzter
    bleepzter almost 2 years

    I have a very weird issue with Microsoft Office.

    I have a common library whose sole purpose is to open whatever word document file type is passed to it (by a full file path...) and save that opened word document as a pdf file.

    The weird issue is that if I consume that library from a windows service, whenever it attempts to open the word document, I get a null... aka, the word document never got opened.

    If however I consume the library from a WPF or Windows Form application I never have any issues. I am aware that there are issues with threading, (Single Thread Appartment) however I have no idea how to fix it to work out of the windows service. :( :( :(

    I would appreciate any help! The Error I get Is the following:

    Exception Message: {"Object reference not set to an instance of an object."} (Referring to the word document). Inner Exception: Null; HResult: -2147467261. Data: ListDictionaryInternal with 0 entries; Stack Trace: at DocumentConverter.ToPdf(String currentWorkingFolderPath, String pathToDocumentToConvert) in c:\Project Files...\DocumentConverter.cs:line 209

    So here is the library function. It requires the Microsoft Office reference, which is created by the 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;
    }
    
  • bleepzter
    bleepzter over 11 years
    There are no issues opening office. The only issue is when the word document is opened... As a service, the word document opened is null. As windows form... the word document opened is actually a word document. The service runs under full admin account. I have logging and the error is extremely non-descript. However it is thrown as a result of having office save a Word Document that is null.
  • Josh E
    Josh E over 11 years
    @bleepzter - "The only issue is when the word document is opened... As a service, the word document opened is null" -- ah, I do see that you've set wordApplication.Visible = false in your code. What does the 'non-descript' error message actually say? Can you edit it into your question? Even if it doesn't help, it will assist others who find this question via search engine
  • bleepzter
    bleepzter over 11 years
    I just added the exception message. Like I said... it is really non descript, but when I attach to the service process it does get thrown on the SaveAs method of the WordDocument because the word document is null. :(
  • bleepzter
    bleepzter over 11 years
    I have read the Office server support manual which is a non-constructive statement of the obvious: "You (aka me...) are screwed.". As a member of the community I was looking for an answer or direction, rather than the obvious. Other people had suggested to create a windows app and within the service create a new process that opens the windows app to do the conversion (obviously without UI.) so that the office runtime can execute properly. @Sameer S had the best suggestion which turned out to be the solution.
  • Yahia
    Yahia over 11 years
    @bleepzter I provided directions which solve the problems AND provided a link with reasons which explicitely say that what you do is not supported (for technical and security and licensing reasons!)...
  • Lasse Christiansen
    Lasse Christiansen over 11 years
    @Yahia +1 - I answered a similar question the other day, and you simply cannot ignore that Microsoft do not recommend a such usage of Word Interop. Further, I think you do a fine job by giving alternative solutions.
  • Lasse Christiansen
    Lasse Christiansen over 11 years
    @bleepzter You write: "@Sameer S had the best suggestion which turned out to be the solution." -> first of all, where is that answer? If that answer is not posted here, please answer your own question and include a link to the original source.
  • Lasse Christiansen
    Lasse Christiansen over 11 years
    @bleepzter Remember the FAQ: "Treat others with the same respect you’d want them to treat you. We’re all here to learn together. Be tolerant of others who may not know everything you know. Bring your sense of humor." - so please stop complaining and start appreciating that people are just trying to help the best they can. It's not our fault if an answer does not meet "your company policies" or whatever.
  • Cole W
    Cole W almost 11 years
    Adding those Desktop folders worked for me. Very obscure but it worked! Word was previously hanging when a windows service was calling a COM dll that was launching word (win 2008r2).
  • John Saunders
    John Saunders over 10 years
    -1: first, the OP is using a Windows Service, not ASP.NET. Second, Office Interop doesn't work reliably from any server-side application.
  • John Saunders
    John Saunders over 10 years
    Note that is may have worked for your situation so far, but in general, does not work
  • MazarD
    MazarD over 9 years
    Many hours looking for the solution and finally found you!! Thank you very much!! it also worked for me. With office 2010 and the windows service running on windows server 2008.
  • Denny Weinberg
    Denny Weinberg over 7 years
    This is crazy!!! It works. Had the error "The document name or path is not valid"
  • HK1
    HK1 almost 7 years
    I'm using Office 2013 (32bit I think) on Server 2012 R2 and this crazy solution still works for that. Thank you so much! You saved the day!!
  • Axemasta
    Axemasta over 4 years
    These folders didn't exist on my server so I created them. INSANE that this is the fix....!!! 🤷
  • Hopeless
    Hopeless over 3 years
    MS Word is much more powerful and not any others can replace it, some can help open/write the file but that's not all what we want. What about printing a word file (silently)? We need a true renderer (not just a reader or writer) and that's when MS Word is not easily replaced.