完成后如何让 Excel 关闭?

How can I get Excel to close when I'm done with it?

这是在 COM API Word 加载项中。是的,通常 Hans Passant's advice to let .NET clean everything up works.

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

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),访问图表对象以更新图表中的数据。

COM 对象需要完全释放,否则 "orphaned" 对象可以将应用程序保留在内存中,即使调用它的代码超出范围。

由于使用了 xlApp,这种特殊情况可能比较特殊(与您之前使用的其他代码相比)。默认情况下,使用 Office 2007 中引入的对象模型处理图表时不需要或不使用 Excel Application 对象(我认为是)。它在问题的代码中使用,以隐藏默认情况下(和设计)可见的 Excel window。但是对象模型并不是为了清理它而设计的——它假定它不存在...

在我的测试中,对象在以下情况下正确释放(参考问题中的代码):

所有 Excel 对象都设置为 null 以相反的顺序实例化,确保 退出 Excel 应用程序,然后尝试将该对象设置为 null:

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”。这确实是 "bare bones" 并且其中一些不再相关,考虑到多年来对 C# 的更改(以 VB.NET 是 "easier" 的方式使其成为 "easier to use")。但是 COM 与 .NET 交互的方式并没有改变,深入...