我在C#(ApplicationClass)中使用Excel互操作,并在finally子句中放置了以下代码:

while (System.Runtime.InteropServices.Marshal.ReleaseComObject(excelSheet) != 0) { }
excelSheet = null;
GC.Collect();
GC.WaitForPendingFinalizers();

尽管这种方法有效,但即使在我关闭Excel之后,Excel.exe进程仍处于后台。它只在我的应用程序被手动关闭后发布。

我做错了什么,或者是否有其他方法可以确保正确处理互操作对象?


当前回答

您需要意识到Excel对您正在运行的文化也非常敏感。

您可能会发现,在调用Excel函数之前,需要将区域性设置为EN-US。这并不适用于所有函数,但适用于其中一些函数。

    CultureInfo en_US = new System.Globalization.CultureInfo("en-US"); 
    System.Threading.Thread.CurrentThread.CurrentCulture = en_US;
    string filePathLocal = _applicationObject.ActiveWorkbook.Path;
    System.Threading.Thread.CurrentThread.CurrentCulture = orgCulture;

即使您正在使用VSTO,这也适用。

有关详细信息:http://support.microsoft.com/default.aspx?scid=kb;我们;第320369季度

其他回答

只是为了给这里列出的众多解决方案添加另一个解决方案,使用C++/ATL自动化(我想您可以使用类似于VB/C#??的东西)

Excel::_ApplicationPtr pXL = ...
  :
SendMessage ( ( HWND ) m_pXL->GetHwnd ( ), WM_DESTROY, 0, 0 ) ;

这对我来说很有魅力。。。

这是唯一对我有效的方法

        foreach (Process proc in System.Diagnostics.Process.GetProcessesByName("EXCEL"))
        {
            proc.Kill();
        }

我一直遵循VVS答案中的建议。然而,为了使这个答案与最新的选项保持同步,我认为我未来的所有项目都将使用“NetOffice”库。

NetOffice是Office PIA的完全替代品,完全不受版本限制。它是一个托管COM包装器的集合,可以处理在.NET中使用Microsoft Office时经常引起此类麻烦的清理。

一些关键功能包括:

大部分与版本无关(记录了与版本相关的功能)无相关性无PIA没有注册无VSTO

我与该项目毫无关联;我真的很欣赏头痛的明显减轻。

两点规则不适用于我。在我的案例中,我创建了一种方法来清理我的资源,如下所示:

private static void Clean()
{
    workBook.Close();
    Marshall.ReleaseComObject(workBook);
    excel.Quit();
    CG.Collect();
    CG.WaitForPendingFinalizers();
}

我不敢相信这个问题已经困扰了世界五年。。。。如果您已经创建了应用程序,则需要在删除链接之前先关闭它。

objExcel = new Excel.Application();  
objBook = (Excel.Workbook)(objExcel.Workbooks.Add(Type.Missing)); 

关闭时

objBook.Close(true, Type.Missing, Type.Missing); 
objExcel.Application.Quit();
objExcel.Quit(); 

当您新建一个excel应用程序时,它会在后台打开一个excel程序。您需要在释放链接之前命令该excel程序退出,因为该excel程序不是您直接控制的一部分。因此,如果链接被释放,它将保持开放!

每个人都很好编程~~