【问题标题】:How to release objects which are created for Excel (C#) [duplicate]如何释放为 Excel(C#)创建的对象 [重复]
【发布时间】:2012-08-05 22:54:46
【问题描述】:

我为 Excel 任务使用了一些对象,例如工作簿、工作表、应用程序。完成 Excel 后,我尝试通过下面的代码发布它们。毕竟,我仍然在任务管理器中看到 EXCEL.EXE。为什么不完全释放?

我的 Excel 任务课程:

Excel._Application app = new Excel.Application();
Excel._Workbook workbook = app.Workbooks.Add(Type.Missing);
Excel._Worksheet worksheet = null;
app.Visible = true;

worksheet.Cells[1, 1] = "test string";

workbook.SaveAs("C:\testfile.xlsx");

object misValue = System.Reflection.Missing.Value;
workbook.Close(true, misValue, misValue);
app.Quit();

releaseObject(worksheet2);
releaseObject(workbook);
releaseObject(app);

releaseObject 类:

    private void releaseObject(object obj)
    {
        try
        {
            System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
            obj = null;
        }
        catch (Exception ex)
        {
            obj = null;
            MessageBox.Show("Unable to release the Object " + ex.ToString());
        }
        finally
        {
            GC.Collect();
        }
    } 

EXCEL.EXE 仍在任务管理器中:

【问题讨论】:

  • 您也可以尝试将appworkbookworksheet 设置为null,以向GC 指示不再需要对这些对象的引用。
  • @barrowc 一针见血。我怀疑这是一个错字。我使用相同的releaseObject(object obj),从来没有遇到过问题......
  • worksheet2 是您猜的错字。分配 null 不起作用。此问题页面中有 3 个好主意,但没有一个有效。这个问题真的让我很烦。如果我关闭应用程序,所有 EXCEL.EXE 文件都会终止。我不关闭它,所有EXCEL.EXE文件都在后台!
  • 你找到解决这个恼人问题的方法了吗?

标签: c# excel


【解决方案1】:

已回答见:

How do I properly clean up Excel interop objects?

基本上 COM 对象是非托管对象 (duh),当它们超出范围时不会被释放。 System.Runtime.InteropServices.Marshal.ReleaseComObject() 可用于在它们最终确定之前释放它们(在垃圾收集器中),但您必须确保保留所有对象的引用: excelApp.Worksheets.Open() 创建两个对象:集合“Worksheets”和使用 Open() 方法打开的“Worksheet”。

【讨论】:

    【解决方案2】:

    使用进程从任务管理器中杀死 EXCEL 对象非常容易,见下文并享受..

    //Kill the all EXCEL obj from the Task Manager(Process)
    System.Diagnostics.Process[] objProcess = System.Diagnostics.Process.GetProcessesByName("EXCEL");
    
    if (objProcess.Length > 0)
    {
        System.Collections.Hashtable objHashtable = new System.Collections.Hashtable();
    
        // check to kill the right process
        foreach (System.Diagnostics.Process processInExcel in objProcess)
        {
            if (objHashtable.ContainsKey(processInExcel.Id) == false)
            {
                 processInExcel.Kill();
            }
        }
        objProcess = null;
    }
    
    //In case of you want to quit what you have created the Excel object from your application //just use below condition in above,
    
        if(processInExcel.MainWindowTitle.ToString()== "")
    

    【讨论】:

      【解决方案3】:

      自从我完成 Office 互操作以来已经有一段时间了(我实际上是在 Outlook 中使用它,但概念应该是相同的)。我能够完全释放一切的唯一方法就是这样做:

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

      试一试……

      【讨论】:

      【解决方案4】:

      这是我无法解决的问题。我以前看过所有这些答案,并且我已经实现了所有这些答案,但仍然 excel 没有关闭。我不得不用蛮力做事。我所做的是创建了一个 BAT 文件并从我的程序中运行它。这是文件的内容:

      Taskkill /F /IM excel.exe
      

      这将调用你所有的 Excel 运行。如果您无法找到不同的解决方案,我会使用它。

      【讨论】:

        【解决方案5】:

        您需要通过这样做来关闭 excel 应用程序,因为它会在后台打开 excel 程序....

        app .Application.Quit();
        

        在你的代码中添加上面的代码行:

            object misValue = System.Reflection.Missing.Value;
            workbook.Close(true, misValue, misValue);
            app .Application.Quit();
            app.Quit();
        

        【讨论】:

        • 没用 :( 试了几次
        猜你喜欢
        • 1970-01-01
        • 2021-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-09
        • 2023-03-08
        • 1970-01-01
        • 2014-04-28
        相关资源
        最近更新 更多