Smaltimento di Microsoft.Office.Interop.Word.Application

(Un po ‘di seguito dal post (che rimane senza risposta): https://stackoverflow.com/q/6197829/314661 )

Utilizzando il seguente codice

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

Sto tentando di aprire e stampare un file a livello di codice.

Il problema è che ogni volta che eseguo il codice precedente viene avviato un nuovo processo WINWORD.exe che ovviamente consuma tutta la memoria.

La class dell’applicazione non sembra contenere un metodo di smaltimento / chiusura o simile.

Dopo un po ‘di ricerca ho (realizzato) e cambiato il codice al seguente.

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

E posso vedere che il numero di riferimento rimanente è zero ma i processi rimangono?

PS: sto usando la versione 14 della libreria Microsoft.Office.Interop.

Forse prova a impostare doc = null e chiama GC.Collect()

Modifica, non proprio il mio codice Ho dimenticato dove l’ho preso ma questo è quello che uso per disporre di Excel, e fa il lavoro forse puoi racimolare qualcosa da questo:

 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! } 

Non hai bisogno di chiamare Quit ?

 app.Quit(); 

La migliore soluzione .. ultimo:

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

Chiudo il documento, quindi l’applicazione, che funziona per me, quindi forzare la 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(); 

Devi chiamare app.Quit() per chiudere l’applicazione. Ho usato sotto il codice e ha funzionato come un fascino per 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(); } 

Prova questo..

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

Penso che il problema principale, su cui nessuno sembra averlo rilevato, è che non dovresti creare un nuovo object Application in primo luogo se Word è già aperto. Quelli di noi che sono stati codificati dai tempi di COM e / o VB6 ricorderanno GetActiveObject. Fortunatamente .Net richiede solo un ProgID.

Il modo consigliato di farlo è il seguente:

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