Search code examples
c#excelcom

properly disposing of Excel COM object in Excel Add in


OK, I believe this question must have been asked a million times, so apologies for a duplicate, but I cannot figure out why I am still getting a COM object in my Task Manager after running this app.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Tools.Ribbon;
using Excel = Microsoft.Office.Interop.Excel;
using Microsoft.Office.Core;
using System.Reflection;
using System.Runtime.InteropServices;

namespace DataDumpTest
{
public partial class DataDumpRibbon
{
    private Excel.Application _xlApp = null;
    private Excel.Workbook _wb = null;
    private Excel.Worksheet _ws = null;

    private void DataDumpRibbon_Load(object sender, RibbonUIEventArgs e)
    {

    }

    private void LoadOpenFileDialog()
    {
        this.openFileDialog1.Filter = "Excel File (*.XLSX) | *.XLSX";
        this.openFileDialog1.Title = "Ariel's Special Definition";
        this.openFileDialog1.Multiselect = false;
    }

    private void btnDataDump_Click(object sender, RibbonControlEventArgs e)
    {
        LoadOpenFileDialog();

        if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        {
            _xlApp = new Excel.Application();
            _xlApp.Visible = false;
            _xlApp.DisplayAlerts = false;
            _xlApp.ScreenUpdating = false;
            _wb = _xlApp.Workbooks.Open(openFileDialog1.FileName);
            _ws = _wb.Worksheets["Sheet1"];

            _ws.UsedRange.Copy(Type.Missing);
            // get range to paste into
            Excel.Worksheet activeWs = Globals.ThisAddIn.Application.ActiveSheet;
            if (activeWs != null)
            {
                Excel.Range rng = activeWs.Cells[1, 1];
                rng.Select();
                Globals.ThisAddIn.Application.ActiveSheet.Paste(Type.Missing, Type.Missing);
            }

            // clean up
            GC.Collect();
            GC.WaitForPendingFinalizers();
            Marshal.FinalReleaseComObject(_ws);
            _wb.Close(Type.Missing, Type.Missing, Type.Missing);
            Marshal.FinalReleaseComObject(_wb);
            _xlApp.Quit();
            Marshal.FinalReleaseComObject(_xlApp);
        }
    }
}
}

So the COM object I am interested in disposing of is the _xlApp, _wb and _ws that I am opening via OpenfileDialog1. When I am debugging this I can see in my task manager that when I hit the button another Excel instance shows up and doesnt disappear until I stop debugger. Shouldn't it be gone when I released them? Am I missing something here?

Ps. This is just a simple copy/paste from one excel to another, but I want to make sure that I get it right here before I go on to the rest of this app.


Solution

  • Hmm, try just using:

    Marshal.ReleaseComObject(YourComApp);
    

    If it still doesn't go, try nulling out the COM object after running the Marshal on it. I know in powershell I have to dump the variable too.