it-swarm.com.de

Warum lässt Microsoft.Office.Interop.Excel.Application.Quit () den Hintergrundprozess laufen?

Mit dem folgenden Code wird ein Microsoft Excel-Hintergrundprozess ausgeführt, bis mein Programm beendet wurde:

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?

11
skinnysoftware

Ich habs!

application.Workbooks! = application.Workbooks

Diese Eigenschaft macht keine Variable verfügbar, sie generiert einen Wert. Bei jedem Zugriff auf die Workbooks-Eigenschaft erstelle ich ein neues COM-Objekt.

Ich habe den Code korrigiert 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);
24
skinnysoftware

Dies ist ein weit verbreitetes Problem bei 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 möglicherweise nicht ordnungsgemäß heruntergefahren werden. Siehe Objekte systematisch freigeben für weitere Informationen. 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 die Verwendung beendet haben. Legen Sie dann in Visual Basic eine Variable auf Nothing fest (null in C #), um den Verweis auf das Objekt freizugeben.

6
Eugene Astafiev

DIESES IS FALSCHE ART, WIE DIESES ZU TUN , aber dies ist der einfachste Weg, 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, alle nicht initialisierten Variablen zu initialisieren, wenn Sie mit ihr arbeiten müssen, und CloseExcelApp () aufzurufen, wenn Sie die App schließen müssen.

2
Andrew