彻底关闭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程序。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法