Disposing of Microsoft.Office.Interop.Word.Application

Viewed 75990

(Somewhat of a follow on from the post (which remains unanswered): https://stackoverflow.com/q/6197829/314661)

Using the following code

Application app = new Application();
_Document doc = app.Documents.Open("myDocPath.docx", false, false, false);
doc.PrintOut(false);
doc.Close();

I am attempting to open and print a file programmatically.

The problem is each time I run the above code a new WINWORD.exe process is started and obviously this quickly eats up all the memory.

The application class doesn't seem to contain a dispose/close or similar method.

After a bit of research I (realized) and changed the code to the following.

 Application app = new Application();
 _Document doc = app.Documents.Open(fullFilePath + ".doc", false, false, false);
 doc.PrintOut(false);
 doc.Close();
 int res = System.Runtime.InteropServices.Marshal.ReleaseComObject(doc);
 int res1 = System.Runtime.InteropServices.Marshal.ReleaseComObject(app);

And I can see the remaining reference count is zero but the processes remain?

PS: I'm using Version 14 of the Microsoft.Office.Interop library.

8 Answers

I think the main issue, which nobody seems to have picked up on, is that you shouldn't be creating a new Application object in the first place if Word is already open. Those of us who have been coding since the days of COM and/or VB6 will remember GetActiveObject. Fortunately .Net only requires a ProgID.

The recommended way of doing this is as follows:

try
{
    wordApp = (word.Application) Marshal.GetActiveObject("Word.Application");
}
catch(COMException ex) when (ex.HResult == -2147221021)
{
    wordApp = new word.Application();
}

Agreed with other posters that GC.Collect() and Marshal.ReleaseComObject() is not needed. If the process still exists after running app.Quit(false), it might be because you're running the app invisible, and there is a prompt that is preventing the application from closing, such as a Document Recovery dialog. If that's the case, you need to add this when creating your application.

app.DisplayAlerts = false;
Related