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

我们在应用程序里面通过创建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程序。

彻底关闭Excle进程的几个方法的更多相关文章

  1. 一张图搞定OAuth2.0 在Office应用中打开WPF窗体并且让子窗体显示在Office应用上 彻底关闭Excle进程的几个方法 (七)Net Core项目使用Controller之二

    一张图搞定OAuth2.0   目录 1.引言 2.OAuth2.0是什么 3.OAuth2.0怎么写 回到顶部 1.引言 本篇文章是介绍OAuth2.0中最经典最常用的一种授权模式:授权码模式 非常 ...

  2. c#关闭excel进程失败的解决方法

    解决方法如下: 1.运行命令dcomcnfg -32,打开组件服务 2.找到execl服务,属性中设置交互式用户 2.设置用户权限 3.设置IIS权限

  3. C# 如何强制关闭WINWORD进程

    private void KillProcess(string processName) //调用方法,传参{try{ Process[] thisproc = Process.GetProcesse ...

  4. windows和linux下关闭Tomcat进程

    windows和linux下解决Tomcat进程 windows下启动Tomcat报错,8080端口号被占用,报错信息如下 两种解决方法,一种是关闭了这个端口号,另外一种是修改Tomcat下的serv ...

  5. win7 win10下80端口被System进程占用的解决方法

    用如下方法可以解决System进程占用80端口的问题:打开RegEdit:开始-运行-输入regedit-调出注册表找到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControl ...

  6. Inno Setup 系列之安装、卸载前检测进程运行情况并关闭相应进程

    需求 最近用 Inno Setup 做一个exe,可是在安装之前要停止正在运行的相应进程或者在卸载之前要停止正在运行的相应进程,可是发现它自身的方法不能满足要求,最后经过度娘的耐心帮助下终于在网上找到 ...

  7. 使用windows操作EXCEL如何关闭EXCEL进程

    经常项目上有导入excel的需求,其实导入一个固定格式的excel数据非常容易,但是,发现一个问题就是,导入excel后,用户在打开excel时,必须要打开2次才能打开excel,这让人很不爽:开始查 ...

  8. Linux系统下如何优雅地关闭Java进程?

    资料出处: http://www.sohu.com/a/329564560_700886 https://www.cnblogs.com/nuccch/p/10903162.html 前言 Linux ...

  9. 解决关闭SSH进程CobaltStrike自动关闭

    解决关闭SSH进程CobaltStrike自动关闭 0x0 那么为什么ssh一关闭,程序就不再运行了? 答:元凶:SIGHUP 信号 让我们来看看为什么关掉窗口/断开连接会使得正在运行的程序死掉. 在 ...

随机推荐

  1. 【二代示波器教程】第15章 FreeRTOS操作系统版本二代示波器实现

    第15章     FreeRTOS操作系统版本二代示波器实现 本章教程为大家讲解FreeRTOS操作系统版本的二代示波器实现.主要讲解RTOS设计框架,即各个任务实现的功能,任务间的通信方案选择,任务 ...

  2. Redis sortedset实现元素自动过期

    这里的自动过期,Redis并没有提供相应的api,但是可以使用一下方法来实现. 需求背景: 给用户返回的文章要求七日内不能重复:文章是存放在java list里边:(这一块就是从db将文章拿出来,然后 ...

  3. Java设计模式之单例模式,笔记完整到不敢想象

    单例模式: 作用 保证一个类只有一个实例,并且提供一个访问该实例的全局访问入口 单例模式的常用 1.Windows的任务管理器2.Windows的回收站,也是一个单例应用3.项目中的读取配置文件的对象 ...

  4. Android OpenSL ES 开发:Android OpenSL 介绍和开发流程说明

    一.Android OpenSL ES 介绍 OpenSL ES (Open Sound Library for Embedded Systems)是无授权费.跨平台.针对嵌入式系统精心优化的硬件音频 ...

  5. [Swift]LeetCode18. 四数之和 | 4Sum

    Given an array nums of n integers and an integer target, are there elements a, b, c, and d in nums s ...

  6. [Swift]LeetCode443. 压缩字符串 | String Compression

    Given an array of characters, compress it in-place. The length after compression must always be smal ...

  7. RxJS简介

    函数式编程 1.声明式(Declarativ) 和声明式相对应的编程⽅式叫做命令式编程(ImperativeProgramming),命令式编程也是最常见的⼀种编程⽅式. //命令式编程: funct ...

  8. linux中一些简便的命令之sort

    1.sort file 直接按照顺序排列 2.sort -r file 按照反序排列 3.sort -t [符号]file 指定符号的分隔符,默认为空格 sort -t ';' file 4.sort ...

  9. 1、MySQL主从同步机制及同步中的问题处理

    http://www.drupal001.com/2012/03/mysql-master-slave-troubles/ http://www.jb51.net/article/33052.htm

  10. C# 之 Socket 简单入门示例

    这个例子只是简单实现了如何使用 Socket 类实现面向连接的通信. 注意:此例子的目的只是为了说明用套接字写程序的大概思路,而不是实际项目中的使用程序.在这个例子中,实际上还有很多问题没有解决,如消 ...