2015-01-13 7 views
8

Der folgende Code lässt eine Microsoft Excel Hintergrundprozess läuft, bis nach meinem Programm verlassen hat:Warum lässt Microsoft.Office.Interop.Excel.Application.Quit() den Hintergrundprozess laufen?

var excelApplication = new Application(); 
var workbooks = excelApplication.Workbooks; 
var workbook = excelApplication.Workbooks.Open(file.FullName); 

workbook.Close(); 
excelApplication.Workbooks.Close(); 
excelApplication.Quit(); 

Marshal.ReleaseComObject(workbook); 
Marshal.ReleaseComObject(workbooks); 
Marshal.ReleaseComObject(excelApplication); 

Warum? Was vermisse ich?

+0

Haben Sie versucht, alles in '// do stuff' zu entfernen? Der Hauptgrund dafür sind einige verbleibende Referenzen, zugewiesene Objekte und so weiter. – DrKoch

+0

Siehe http://stackoverflow.com/questions/9962157/safely-disposing-excel-interop-objects-in-c –

+0

In meinem Test gab es nichts als den Kommentar. Der Code, den ich gepostet habe, war der vollständige/genaue Code. – skinnysoftware

Antwort

16

Verstanden!

Application.Workbooks! = Application.Workbooks

Diese Eigenschaft aussetzen keine Variable, erzeugt sie einen Wert. Jedes Mal, wenn ich auf die Workbooks-Eigenschaft zugreife, erstelle ich ein neues COM-Objekt.

Ich reparierte den Code und alles ist gut. Danke an alle.

var excelApplication = new Application(); 
var workbooks = excelApplication.Workbooks; 
var workbook = workbooks.Open(pathToExcelWorkbook); // Fixed 

workbook.Close(); 
workbooks.Close(); 
excelApplication.Quit(); 

Marshal.ReleaseComObject(workbook); 
Marshal.ReleaseComObject(workbooks); 
Marshal.ReleaseComObject(excelApplication); 
+0

Könnten Sie bitte die richtige Antwort markieren? –

+2

Hallo @eugene - Ihre Antwort hat mich sicherlich in die richtige Richtung geführt, aber ich fand es nicht spezifisch genug, um das ganze Problem zu lösen. Wenn Sie Zeile 3 in meinen zwei Codebeispielen vergleichen, werden Sie feststellen, dass das Problem darin lag, dass ich nicht verstanden habe, dass die Eigenschaft "Arbeitsmappen" immer ein neues Objekt zurückgibt. – skinnysoftware

5

Dies ist ein weit verbreitetes Problem mit Office-Anwendungen. Alle Excel-Add-Ins/Automatisierungsanwendungen sollten ihre Verweise auf Excel-Objekte systematisch freigeben, wenn sie nicht mehr benötigt werden. Wenn Sie den Verweis auf Excel-Objekte nicht systematisch freigeben, kann Microsoft Office Excel nicht ordnungsgemäß heruntergefahren werden. Weitere Informationen finden Sie unter Systematically Releasing Objects. Es bezieht sich auf Outlook, aber die gleichen Prinzipien können auf alle Office-Anwendungen angewendet werden.

Verwenden Sie System.Runtime.InteropServices.Marshal.ReleaseComObject, um ein Excel-Objekt freizugeben, wenn Sie es nicht mehr verwenden. Setzen Sie dann in Visual Basic eine Variable auf Nothing (null in C#), um den Verweis auf das Objekt freizugeben.

+2

Scheint wie eine vernünftige Antwort, nicht sicher, warum Sie downvoted wurden – Kehlan

+0

Ist dies immer noch der Fall in den neueren Office-Versionen? Der von Ihnen gepostete Link enthält Links zu den 2007-Informationen. Und wenn ich die Version der Dokumentation ändere ("Andere Versionen" Dropdown) gibt es keine Informationen über System.Runtime.InteropServices.Marshal.ReleaseComObject für 2010 oder 2013. –

+1

Das gleiche kann auf neuere Office-Versionen angewendet werden. –

0

DIES IST WIE DIESE WRONG WAY zu tun, aber das ist einfachste Weg, um das Problem zu beheben:

[DllImport("user32.dll")] 
    private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); 

    private Application _excelApp; 
    private Workbook _excelWorkBook; 
    private Worksheet _excelSheet; 

    private void CloseExcelApp() 
    { 
     int hWnd = _excelApp.Application.Hwnd; 
     uint processID; 

     GetWindowThreadProcessId((IntPtr)hWnd, out processID); 
     Process.GetProcessById((int)processID).Kill(); 

     _excelWorkBook = null; 
     _excelApp = null; 
     _excelSheet = null; 
    } 

alles, was Sie brauchen, ist es, alle nicht initialisierten Variablen init, wenn Sie brauchen um damit zu arbeiten, und rufen Sie CloseExcelApp() auf, wenn Sie die App schließen müssen.

Verwandte Themen