【问题标题】:Excel does not Quit C#Excel 不退出 C#
【发布时间】:2018-05-16 22:15:00
【问题描述】:

我正在用 C# 编写此特定代码以写入 excel 文件。

public partial class WriteExcelForm : Form
{
    public WriteExcelForm()
    {
        InitializeComponent();
    }

    private void writeExcelButton_Click(object sender, EventArgs e)
    {
        Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
        if (xlApp == null)
        {
            MessageBox.Show("Excel is not installed!!!");
            return;
        }

        Excel.Workbooks xlWorkBooks = xlApp.Workbooks;
        Excel.Workbook xlWorkBook = xlWorkBooks.Add(Type.Missing);
        Excel.Worksheet xlWorkSheet = xlWorkBook.ActiveSheet;
        xlWorkSheet.Name = "sample";

        Excel.Range range1 = (Excel.Range)xlWorkSheet.Cells[1, 1];
        range1.Value = "dhiraj";

        Excel.Range range2 = xlWorkSheet.Range["A2"];
        range2.Value = "dhiraj";

        xlWorkBook.SaveAs("C:\\output.xlsx");

        //Properly closing the excel app
        GC.Collect();
        GC.WaitForPendingFinalizers();

        xlWorkBook.Close(false, Type.Missing, Type.Missing);
        xlApp.Quit();

        Marshal.FinalReleaseComObject(range1);
        Marshal.FinalReleaseComObject(range2);
        Marshal.FinalReleaseComObject(xlWorkSheet);
        Marshal.FinalReleaseComObject(xlWorkBook);
        Marshal.FinalReleaseComObject(xlWorkBooks);
        Marshal.FinalReleaseComObject(xlApp);
    }
}

如果我运行此代码,excel.exe 不会退出,而是继续在后台运行。

但是,如果我注释掉这一行

        Excel.Range range1 = (Excel.Range)xlWorkSheet.Cells[1, 1];
        range1.Value = "dhiraj";

excel.exe 优雅地退出。

我在这里错过了什么?

编辑: 我已经解决了我的问题。发布我的发现作为答案。

P.S:不知道为什么我被否决了,我在发布这个问题之前做了很多研究。

【问题讨论】:

标签: c# excel c#-4.0 vba


【解决方案1】:

所以,我在提出问题后继续我的研究,并找到了这个特定的链接 How do I properly clean up Excel interop objects?

现在在这个特定的链接中,三个答案放在一起帮助了我。

第一个答案是这个特定的https://stackoverflow.com/a/158752/2241802 它说要避免使用“永远不要对 COM 对象使用两个点”。

第二个答案是这个https://stackoverflow.com/a/159419/2241802 这个答案是指如何实际使用 excel 对象,遵循这一点非常重要,因为我不会是唯一一个处理我的代码的开发人员。

第三个答案https://stackoverflow.com/a/1893653/2241802 讨论垃圾收集器在发布模式和调试模式下的行为有何不同。

这就是我的问题,当我在发布模式下运行粘贴在问题中的代码时,它运行良好,并且 excel.exe 正常退出。

但是,为了让它在调试模式下工作,我接受了上面第三个答案链接的建议,并创建了一个实现 excel 写作内容的函数。

【讨论】:

    【解决方案2】:

    找到下面的代码

    protected void Button3_Click(object sender, EventArgs e)
        {
            int randomvalue = new Random().Next(10);
            try
            {
                filename = Server.MapPath("~/Reports/Tro_Reports" + randomvalue + ".xlsx");
                using (var getReportCollection = new DataSet1())
                {
                    using (var tableCollection = getReportCollection.Tables["SheetNames"])
                    {
                        var excelApplication = new Microsoft.Office.Interop.Excel.Application();
    
                        try
                        {
                            var wb = excelApplication.Workbooks.Add();
    
                            var collection = new Microsoft.Office.Interop.Excel.Worksheet[20];
    
                            for (var i = 0; i < tableCollection.Columns.Count; i++)
                            {
                                collection[i] = wb.Worksheets.Add();
                                collection[i].Name = tableCollection.Columns[i].ToString();
                            }
                            var thisWorksheet = collection[2];
                            var thisRange = thisWorksheet.Range["A1"];
                            thisRange.Value = "Event Summary Report";
    
                            wb.SaveAs(filename);
                            wb.Close();
                        }
                        finally
                        {
                            Marshal.ReleaseComObject(excelApplication);
                        }
                    }
                }
            }
            catch (ExternalException ex)
            {
    
            }
        }
    

    上面的代码 sn-p 可以很好地关闭您的 Excel 工作表。

    【讨论】:

    • 我怀疑xlWorkBook.Close(false, Type.Missing, Type.Missing); 行正在关闭工作簿。
    • 是的。它可以关闭工作簿。在 GC.Collect() 之后需要关闭工作簿吗?
    • 在 OP 的代码中调用 GC.Collect(); GC.WaitForPendingFinalizers(); 实际上什么也没做。
    猜你喜欢
    • 2012-07-29
    • 2018-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多