it-swarm.com.de

Entsorgen von Microsoft.Office.Interop.Word.Application

(Etwas Follow-up von der Post (die unbeantwortet bleibt): https://stackoverflow.com/q/6197829/314661 )

Verwenden Sie den folgenden Code

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

Ich versuche, eine Datei programmgesteuert zu öffnen und zu drucken.

Das Problem ist, dass jedes Mal, wenn ich den obigen Code ausführe, ein neuer WINWORD.exe-Prozess gestartet wird und dies offensichtlich schnell den gesamten Speicher auffrisst.

Die Anwendungsklasse scheint keine dispose/close- oder ähnliche Methode zu enthalten.

Nach ein wenig Recherche habe ich (realisiert) und den Code wie folgt geändert.

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

Und ich kann sehen, dass der verbleibende Referenzzähler Null ist, aber die Prozesse bleiben?

PS: Ich verwende Version 14 der Microsoft.Office.Interop-Bibliothek.

37

Versuchen Sie vielleicht, doc = null Einzustellen und GC.Collect() aufzurufen.

Bearbeiten, nicht wirklich mein eigener Code Ich vergesse, woher ich ihn habe, aber das ist es, was ich verwende, um Excel zu entsorgen, und es erledigt den Job. Vielleicht kannst du etwas daraus lernen:

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

Müssen Sie Quit nicht aufrufen?

app.Quit();
51
Enigmativity

Die beste Lösung .. zuletzt:

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);
}
3
T Bass

Sie müssen app.Quit() aufrufen, um die Anwendung zu schließen. Ich habe den folgenden Code verwendet und es hat wie ein Zauber für mich funktioniert -

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

Ich denke, das Hauptproblem, das niemand aufgegriffen zu haben scheint, ist, dass Sie nicht in erster Linie ein neues Anwendungsobjekt erstellen sollten, wenn Word bereits geöffnet ist. Diejenigen von uns, die seit den Tagen von COM und/oder VB6 codiert haben, werden sich an GetActiveObject erinnern. Glücklicherweise benötigt .Net nur eine ProgID.

Die empfohlene Vorgehensweise lautet wie folgt:

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

Versuche dies..

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();
1
Asiri Jayaweera

Ich schließe das Dokument, dann die Anwendung, die für mich funktioniert, und erzwinge dann die 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();
0
gangelo