By Maxim Gershkovich


2011-07-21 14:11:36 8 Comments

(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 comments

@Jordan 2019-11-07 18:48:09

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;

@Charlie 2018-08-15 22:42:01

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();
}

@Asiri Jayaweera 2018-03-14 08:50:51

Try this..

doc.Close(false);
app.Quit(false);
if (doc != null)
    System.Runtime.InteropServices.Marshal.ReleaseComObject(doc);
if (app != null)
    System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
doc = null;
app = null;
GC.Collect();

@T Bass 2015-08-25 06:20:20

The best solution.. last:

try {

    Microsoft.Office.Interop.Word.Application appWord = new Microsoft.Office.Interop.Word.Application();
    appWord.Visible = false;
    Microsoft.Office.Interop.Word.Document doc = null;
    wordDocument = appWord.Documents.Open((INP), ReadOnly: true);

    wordDocument.ExportAsFixedFormat(OUTP, Microsoft.Office.Interop.Word.WdExportFormat.wdExportFormatPDF);

    // doc.Close(false); // Close the Word Document.
    appWord.Quit(false); // Close Word Application.
} catch (Exception ex) {
    Console.WriteLine(ex.Message + "     " + ex.InnerException);
}

@a1ashiish 2013-12-12 09:35:07

You need to calls app.Quit() to close the application. I used below code & it worked like a charm for me -

try
{
   Microsoft.Office.Interop.Word.Application wordApp = new Microsoft.Office.Interop.Word.Application();
   wordApp.Visible = false;
   Microsoft.Office.Interop.Word.Document doc = null;

   //Your code here...

   doc.Close(false); // Close the Word Document.
   wordApp.Quit(false); // Close Word Application.
}
catch (Exception ex)
{
   MessageBox.Show(ex.Message + "     " + ex.InnerException);
}
finally
{
   // Release all Interop objects.
   if (doc != null)
      System.Runtime.InteropServices.Marshal.ReleaseComObject(doc);
   if (wordApp != null)
      System.Runtime.InteropServices.Marshal.ReleaseComObject(wordApp);
   doc = null;
   wordApp = null;
   GC.Collect();
}

@Unnie 2015-01-20 09:46:24

Weird how it worked for you coz, your code should give build error , since doc and wordApp is created inside try and it wont be available in finally.

@MickyD 2015-11-28 04:31:35

There is no need for GC.Collect() nor Marshal.ReleaseComObject() if you close the document and quit the application

@Enigmativity 2011-07-21 14:27:43

Do you not need to call Quit?

app.Quit();

@Matias Masso 2019-08-28 17:15:52

I got error BC30456: 'Quit' is not a member of 'Application'

@Enigmativity 2019-08-29 09:54:08

@MatiasMasso - The code is correct. You musn't have an instance of Application.

@gangelo 2011-07-21 14:24:36

I close the document, then the application, that works for me, then force garbage collection.

// Document
object saveOptionsObject = saveDocument ? Word.WdSaveOptions.wdSaveChanges : Word.WdSaveOptions.wdDoNotSaveChanges;
this.WordDocument.Close(ref saveOptionsObject, ref Missing.Value, ref Missing.Value);

// Application
object saveOptionsObject = Word.WdSaveOptions.wdDoNotSaveChanges;
this.WordApplication.Quit(ref saveOptionsObject, ref Missing.Value, ref Missing.Value); 

GC.Collect();
GC.WaitForPendingFinalizers();

@MickyD 2015-11-28 04:32:58

There is no need for GC.Collect() nor Marshal.ReleaseComObject() if you close the document and quit the application

@Nick 2011-07-21 14:18:02

Perhaps try setting doc = null and calling GC.Collect()

Edit, not really my own code I forget where I got it but this is what I use to dispose of Excel, and it does the job maybe you can glean something from this:

public void DisposeExcelInstance()
{
    app.DisplayAlerts = false;
    workBook.Close(null, null, null);
    app.Workbooks.Close();
    app.Quit();
    if (workSheet != null)
        System.Runtime.InteropServices.Marshal.ReleaseComObject(workSheet);
    if (workBook != null)
        System.Runtime.InteropServices.Marshal.ReleaseComObject(workBook);
    if (app != null)
        System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
    workSheet = null;
    workBook = null;
    app = null;
    GC.Collect(); // force final cleanup!
}

@Maxim Gershkovich 2011-07-21 14:20:39

Not a bad idea. Just tried it though and didnt seem to help.

@Maxim Gershkovich 2011-07-21 14:25:18

Absolute legand. App.Quit() was the key... Thank you!

@gangelo 2011-07-21 14:27:32

This is an Excel example.

@Nick 2011-07-21 14:28:29

@gangelo, I realize that, but it is still Office Interop so I posted it in hopes that it would lead him to the answer, which it did.

@Lukas Huzen 2012-02-22 11:02:54

to use GC.Collect is not so good idea it wil do an total clean up with GC. GC.Collect(3) would be better regarding to the GC.Collect function. but i agree with @Maxim app.Quit() is better

@Nick 2012-02-22 13:53:12

@LukasHuzen while I agree that it is better practice to specify the generation with GC.Collect(), not calling it at all is not the answer. Perhaps it is an issue with 2010 as that is the only version I have tested with, but simply calling app.Quit() still leaves the process hanging in the background.

@Yandros 2012-06-14 21:44:14

GC.Collect() is like Betelgeuse: you have to call it three times for it to respond in any observable way.

@Nimesh Madhavan 2013-01-28 20:12:40

Calling GC.Collect from application is not a good idea. Let dotnet framework decide when it is best to do a GC.

@MickyD 2015-11-28 04:32:10

There is no need for GC.Collect() nor Marshal.ReleaseComObject() if you close the document and quit the application

@Andrew Rondeau 2016-10-07 18:19:33

Calling GC.Collect is really only useful for diagnostics. If something "works" after calling GC.Collect, either something needs explicit cleanup, or there's a bug in libraries that you're using.

Related Questions

Sponsored Content

4 Answered Questions

[SOLVED] How to properly close/terminate WINWORD.EXE/Word interop?

12 Answered Questions

[SOLVED] Do HttpClient and HttpClientHandler have to be disposed?

14 Answered Questions

[SOLVED] Finalize vs Dispose

  • 2009-04-09 05:00:43
  • tush1r
  • 130840 View
  • 207 Score
  • 14 Answer
  • Tags:   c# dispose

13 Answered Questions

[SOLVED] Finalize/Dispose pattern in C#

11 Answered Questions

[SOLVED] Do you need to dispose of objects and set them to null?

1 Answered Questions

2 Answered Questions

[SOLVED] Will a C# class destructor be called when the class contains static fields?

  • 2017-01-26 18:20:20
  • Mike Lowery
  • 338 View
  • 0 Score
  • 2 Answer
  • Tags:   c# static finalizer

0 Answered Questions

Automate converting office documents to pdf in c#

1 Answered Questions

[SOLVED] Delay when creating Microsoft.Office.Interop.Word.Application

Sponsored Content