在 Excel 添加中正确处理 Excel COM 对象

properly disposing of Excel COM object in Excel Add in

好吧,我相信这个问题一定已经被问过一百万次了,所以很抱歉重复,但我不明白为什么在 运行 这个应用程序之后我的任务管理器中仍然有一个 COM 对象.

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

所以我有兴趣处理的 COM 对象是我通过 OpenfileDialog1 打开的 _xlApp、_wb 和 _ws。当我调试它时,我可以在我的任务管理器中看到,当我按下按钮时,另一个 Excel 实例出现并且在我停止调试器之前不会消失。我放出来的时候不应该没了吗?我在这里错过了什么吗?

Ps。这只是一个简单的 copy/paste 从一个 excel 到另一个 excel ,但我想确保在我继续这个应用程序的其余部分之前我在这里得到它。

嗯,尝试使用:

Marshal.ReleaseComObject(YourComApp);

如果还是不行,请尝试在 运行 Marshal 之后取消 COM 对象。我知道在 powershell 中我也必须转储变量。