zoukankan      html  css  js  c++  java
  • 彻底关闭Excle进程的几个方法

    之前研究过的问题,最近有朋友问,这里再总结下做一个笔记。

    我们在应用程序里面通过创建Excle应用对象打开Excle的情况下,如果不注意几个问题,可能无法彻底关闭Excle进程,来考察下面的几种情况:

            public static void startexcel()
            {
                var  excel = new Microsoft.Office.Interop.Excel.Application();
                excel.Visible = true;
                var book=  excel.Application.Workbooks.Open("D:\Book1.xlsx");
            }

    上面的代码打开了一个工作簿,Excel启动了一个独立进程并且呈现界面给用户,不会再犯方法结束后关闭Excel。这种情况下本意是为了让用户决定何时关闭工作簿。

    结果,当用户手工关闭工作簿后,Excle进程没有关闭,这是因为我们的.NET 托管代码打开的Excle的非托管代码,.NET运行时没有释放相关的句柄,需要加上下面几行代码来释放:

            public static void startexcel()
            {
                var  excel = new Microsoft.Office.Interop.Excel.Application();
                excel.Visible = true;
                var book=  excel.Application.Workbooks.Open("D:\Book1.xlsx");
    
                System.Runtime.InteropServices.Marshal.ReleaseComObject(excel);
                excel = null;
                GC.Collect();
            }

    上面的代码,Marshal.ReleaseComObject 会释放COM组件对象,这里是excel,然后,代码设置 excel=null,这样紧接着执行垃圾回收才有效,否则,无法回收excel句柄。

    注意,执行上面的代码并不会关闭了Excel进程,它只是释放了Excle进程句柄与.NET运行时的关系。

    当用户在外面手工关闭Excle窗体后,Excle进程才会真正从任务管理器消失。

    有朋友可能说,我没有加上面三行代码也能够关闭Excle进程啊。

    没错,上面的代码只不过是立即释放了Excle这种非托管资源。注意到我们的 excle对象是一个局部对象,所以当方法结束后,excle对象已经在方法堆栈上被清空了,只需要在外面合适的时候调用下垃圾回收,即可实现彻底关闭Excle进程的效果:

    startexcel();
    GC.Collect();
    Console.WriteLine("excel close ok.");

    如果我们的Excel进程不是由用户关闭而是要程序自动关闭怎么办?

    这个时候只需要调用Excle应用程序对象的关闭方法即可。

    完整的代码如下,并且下面的代码演示了Excle进程打开一个宏文件,然后再打开工作簿,处理事件,最后关闭Excle窗体,关闭进程清理资源的功能。

    Excle的工作簿保存和关闭事件有时候比较有用,比如保存工作簿的时候就上传一份工作簿副本到服务器。

     public static void startexcel()
            {
                var  excel = new Microsoft.Office.Interop.Excel.Application();
                excel.Visible = true;
                excel.Workbooks.Open("C:\A1000.xla");
                var book=  excel.Application.Workbooks.Open("D:\Book1.xlsx");
                excel.WorkbookBeforeSave += Excel_WorkbookBeforeSave;
                excel.WorkbookBeforeClose += Excel_WorkbookBeforeClose;
                book.Close();
                excel.Quit();
                System.Runtime.InteropServices.Marshal.ReleaseComObject(excel);
                excel = null;
                GC.Collect();
            }
    
            private static void Excel_WorkbookBeforeClose(Workbook Wb, ref bool Cancel)
            {
                Console.WriteLine("Excel 关闭,title:" + Wb.Title);
            }
    
            private static void Excel_WorkbookBeforeSave(Workbook Wb, bool SaveAsUI, ref bool Cancel)
            {
                Console.WriteLine("Excel保存,title:"+Wb.Title);
            }

    注:

    本文的做法,也适用于关闭Word等其它Office程序。

  • 相关阅读:
    ArrayList用法
    MessageBox
    将文本文件导入Sql数据库
    在桌面和菜单中添加快捷方式
    泡沫排序
    Making use of localized variables in javascript.
    Remove double empty lines in Visual Studio 2012
    Using Operations Manager Connectors
    Clear SharePoint Designer cache
    Programmatically set navigation settings in SharePoint 2013
  • 原文地址:https://www.cnblogs.com/bluedoctor/p/8777208.html
Copyright © 2011-2022 走看看