首页 > 解决方案 > 完成后如何让 Excel 关闭?

问题描述

这是在 COM API Word AddIn 中。是的,通常Hans Passant 建议让 .NET 清理所有内容是可行的。

但它不适用于以下情况 - 我已经测试正常运行(没有调试器)并将其缩小到这个特定代码:

private Chart chart;
private bool displayAlerts;
private Application xlApp;


Chart chart = myShape.Chart;

ChartData chartData = chart.ChartData;
chartData.Activate();

WorkbookData = (Workbook)chartData.Workbook;
xlApp = WorkbookData.Application;
displayAlerts = xlApp.DisplayAlerts;
xlApp.Visible = false;
xlApp.DisplayAlerts = false;
WorksheetData = (Worksheet)WorkbookData.Worksheets[1];
WorksheetDataName = WorksheetData.Name;
WorksheetData.UsedRange.Clear();

// ... do a bunch of stuff including writing to the worksheet

xlApp.DisplayAlerts = displayAlerts;
WorkbookData.Close(true);

我认为问题很可能是 Word 给了我这个工作簿,所以谁知道它在做什么来实例化 Excel。但即使在我退出 Word 之后,Excel 实例仍在运行。

同样,在 Word(不是 Excel)中,访问图表对象以更新图表中的数据。

标签: ms-wordoffice-interopexcel-interop

解决方案


COM 对象需要完全释放,否则“孤立”对象可以将应用程序保留在内存中,即使在调用它的代码超出范围之后也是如此。

由于使用了xlApp. 默认情况下,Application使用 Office 2007 中引入的对象模型处理图表时不需要或使用 Excel 对象(我认为是这样)。它在问题的代码中用于隐藏默认情况下(和设计)可见的 Excel 窗口。但是对象模型并非旨在处理清理它 - 它假设它不存在......

在我的测试中,对象在(引用问题中的代码)时正确释放:

所有 Excel 对象都null 按照它们被实例化的相反顺序设置为,确保在尝试将该对象设置为之前退出nullExcel 应用程序:

WorksheetData = null; 
WorkbookData = null; 
xlApp.Quit(); 
xlApp = null; 

然后,当使用 COM 点表示法时,C# 倾向于在幕后创建对象——这些对象并不总是被正确地清理(释放)。因此,最好为所使用的层次结构的每个级别创建一个对象。(注意:VBA 没有这个问题,因此从 VBA 示例或宏记录器中提取的任何代码都需要在这方面重新工作。)从问题中的代码来看,这会影响WorksheetData.UsedRange.Clear();

Excel.Range usedRng = WorksheetData.UsedRange; 
usedRng.Clear(); 
usedRng = null; 

以及标准清理,以确保在可预测的时刻发布所有内容:

GC.Collect(); 
GC.WaitForPendingFinalizers();
GC.Collect(); 
GC.WaitForPendingFinalizers();

当出现这种情况时,我总是参考 Andrew Whitechapel 的“.NET Development for Office”。考虑到多年来对 C# 的更改(以使其“更容易使用”,就像 VB.NET“更容易”一样),这真的是“简单的骨头”,其中一些不再相关。但是 COM 与 .NET 交互的方式并没有改变,在内心深处......


推荐阅读