Microsoft.Interop对象获胜';t退出或“退出”;释放”;

本文关键字:退出 释放 Microsoft 对象 获胜 Interop | 更新日期: 2023-09-27 18:26:25

每次运行此代码时,对象都不会关闭。我仍然有一个excel.exe在任务管理器中运行。即使我将objects设置为null,仍然没有。我甚至尝试过使用objects.Quit()方法。

我在这里做错了什么?

    private bool ValidateQM()
    {
        //setup the objects
        Excel.Application oXL = null;
        Excel.Workbook oWB = null;
        Excel.Worksheet oSheet = null;
        int hWnd = 0;
        try
        {
            //Start Excel and get Application object.
            oXL = new Excel.Application();
            hWnd = oXL.Application.Hwnd;
            oXL.Visible = false;
            //Open the workbook.
            oWB = oXL.Workbooks.Open(workingForm, 0, false, 5, "", "", false, Excel.XlPlatform.xlWindows, "",true, false, 0, true, false, false);
            //Get the Worksheet
            oSheet = oWB.Worksheets[1];
            //Check the date values
            string mydatetime = oSheet.Cells[5, 33].Text.ToString() + " " + oSheet.Cells[7, 33].Text.ToString();
            string dateofscore = oSheet.Cells[3, 12].Text.ToString();
            DateTime.Parse(mydatetime); //make my string a real boy
            DateTime.Parse(dateofscore);
            // Cleanup 
            GC.Collect();
            GC.WaitForPendingFinalizers();
            System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oSheet);
            //oWB.Close();
            System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oWB);
            //oXL.Quit();
            System.Runtime.InteropServices.Marshal.FinalReleaseComObject(oXL);
            return true;
        }

Microsoft.Interop对象获胜';t退出或“退出”;释放”;

你没有违反hWnd = oXL.Application.Hwnd 行中的"不要使用2个点"规则吗?是否查看与ASP.NET不兼容的Excel互操作库?了解更多信息。

当您调用GC.Collect()时,oXL和oWB对象仍在作用域中,因此有一个对它们的引用处于活动状态。因此,GC.Collect()不会触及它们。如果您想确保它们是垃圾收集的,请将它们设置为null,这样在调用GC.Collect()时就不会有活动的引用。此外,您可能希望对活动工作簿调用Close(),对Excel应用程序调用Quit()。您还可以使用大括号{}将所有内容放在自己的范围内,这样所有内容都会一起超出范围。

        // Cleanup 
        oWB.Close(false);
        oWB = null;
        oXL.Quit();
        oXL = null;
        hWnd = null;
#if (DEBUG_SPEED_UP_GC)
        GC.Collect();
        GC.WaitForPendingFinalizers();
#endif

编辑:请注意,手动调用垃圾回收是个坏主意。我假设您这样做只是为了在GC发生时进行调试以加快速度,所以我添加了#if。

我假设没有抛出异常,并且您没有显示的catch处理程序不会为您的问题做任何恶意的事情。

我甚至尝试过使用对象的Quit方法

除非有一些针对这一点的书面建议,否则我不明白为什么你不总是打电话给Quit来表示你已经完成了应用程序。

//Start Excel and get Application object. oXL = new
Excel.Application();
hWnd = oXL.Application.Hwnd;
oXL.Visible = false;

即使您正在更改不属于自己的窗口的可见性,如果Excel在退出时显示警告,会发生什么?在父窗口上将Visible设置为false将对用户造成模糊。

为了进行调试,请尽量不要隐藏窗口。

这里有一些关于如何防止Excel生成需要交互关注的警告的信息。它的基本要点:

DisplayAlerts = false
AskToUpdateLinks = false
AlertBeforeOverwriting = false
Interactive = false
Visible = false
FeatureInstall = 0 'msoFeatureInstallNone

您正在交互式用户会话中运行应用程序,对吗?因为不支持任何其他内容:

Microsoft目前不建议也不支持,从任何无人值守、,非交互式客户端应用程序或组件(包括ASP,ASP.NET、DCOM和NT服务),因为Office可能表现出不稳定Office在此环境中运行时的行为和/或死锁。