VSTO的Excel对象模型提供了托管代码对Excel的操作。但是它的实现时通过RCW(Runtime Com Wrapper)实现的,所以无法完全按照托管代码的运行方式操作。COM的资源释放时通过引用计数的方式实现,不同于CLR的GC机制,在引用计数没有设置为0的情况下,是不会回收资源的。所以,很多情况下,在操作Excel的时候,进程无法结束,其实就是因为Excel的COM计数器没有置0.

那么,如何才能正确地将计数器置0呢?简单代码如下。

            //启动Excel的程序
Excel.Application app = new Excel.Application(); //获取Excel的所有工作簿,注意,不可以使用.net级联方式,即如app.Workbooks.Add()
//必须每个变量都设置引用,这样才可以逐个释放变量,切记,重中之重
Excel.Workbooks wbs = app.Workbooks;
//获取一个工作簿
Excel.Workbook wb = wbs.Add();
//获取当前工作表
Excel.Worksheet ws = wb.ActiveSheet; //声明一个表示Excel区域的变量,并利用其对Excel进行操作
Excel.Range rng;
rng = ws.Range["A1"];
rng.Value2 = "Hello";
//将该变量引用的Com对象的计数器设置为0,并设置引用为null,释放对象
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(rng);
rng = null;
//同上
rng = ws.Range["A2"];
rng.Value2 = "Again";
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(rng);
rng = null; //释放工作表
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(ws);
ws = null; //释放工作簿集合
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(wbs);
wbs = null; //保存文档
wb.SaveAs(@"d:\hello.xlsx"); //释放工作簿
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(wb);
wb = null; //通知Excel主机退出程序
app.Quit(); //最后,释放Excel主机的引用计数器
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(app);
app = null;

如此,进程中的Excel将自动退出,我们也就避免强制结束进程带来的Excel报错问题。

这里的要点就是:任何一个Com对象的引用在指向其他对象之前必须显示释放其对该Com的引用。最后,释放所有的Excel对象的引用计数!

关于VSTO调用Excel后进程无法退出的解决方案:的更多相关文章

  1. wxPython 对话框关闭后进程无法退出的原因

    wxPython中不要用对话框作为主程序wx.Dialog,这会导致程序关闭后进程无法退出.一种可行的做法是用wx.Frame代替

  2. 解决C#使用Microsoft.Office.Interop.Excel操作Excel后进程一直存在的问题

    This resolved the issue for me. Your code becomes: public Excel.Application excelApp = new Excel.App ...

  3. 解决在IIS中调用Microsoft Office Excel组件后进程无法正常退出的问题

    来源:http://www.cnblogs.com/ahui/archive/2013/03/05/2944441.html 有一个项目用到Excel组件产生报表,本以为这个通用功能是个很简单的cas ...

  4. C#导出Excel后关闭进程EXCEL.EXE

    在C#中使用Microsoft.Office.Interop.Execl 导出excel 表格时,将以下两个属性亩后,在导完后, Excel.exe 进程无法关闭. // excel app 是否可见 ...

  5. 使用脚本调用maven命令后脚本直接退出问题

    在带有maven命令的bat脚本执行的时候,执行完一个mvn 目标后会自动退出,pause命令也无效. 原因:mvn本身是一个bat命令,因此在exit退出的时候,整个脚本进程将退出,加入call命令 ...

  6. Windows批处理 调用程序后 不等待子进程 父进程继续执行命令

    从DOS过来的老鸟应该都知道批处理,这个功能在WINDOWS中仍然保留着.批处理 说白了就是把一系列DOS命令写在一个文本文件里,然后把这个文件命名为XXX.bat(WINXP以后的系统也可以命名为* ...

  7. 由STL map调用clear后,内存不返还给操作系统的问题出发,探讨glibc malloc/free行为(转)

    1. 问题 我们的程序有几十个线程,每个线程拥有一个std::map,每个线程都要向自己的std::map中插入大量的数据,但每个数据只有几十字节:当使用完std::map,调用map.clear() ...

  8. 【转载】详解CreateProcess调用内核创建进程的过程

    原文:详解CreateProcess调用内核创建进程的过程 昨天同学接到了腾讯的电面,有一题问到了CreateProcess创建进程的具体实现过程,他答得不怎么好吧应该是, 为了以防万一,也为了深入学 ...

  9. 是什么在.NET程序关闭时阻碍进程的退出?

    在平时使用软件或是.NET程序开发的过程中,我们有时会遇到程序关闭后但进程却没有退出的情况,这往往预示着代码中有问题存在,不能正确的在程序退出时停止代码执行和销毁资源.这个现象有时并不容易被察觉,但在 ...

随机推荐

  1. css之入门篇

    今日学习终于到了css,css可以实现很多表现出很酷的界面,而css的出现是为了解决 HTML结构上写样式出现一片混乱现象而应运而生的语言,在以前样式都是和结构一起写的, 不分彼此,而这样大大增加了代 ...

  2. Android 发布可穿戴设备 SDK 的开发者预览版

    今早上安卓官网查资料,发现网站上赫然显示着"Android Wear"几个大字.难道……?点进去看,果然,Android发布了可穿戴设备的SDK的开发者预览版. 其中这第五张图…… ...

  3. Objective-c中 isEqual ,isEqualToString , == 三者的区别

    首先 OC中的对象都是用指针表示,方法的调用是基于消息机制实现,== 比较的自然是指针指向的地址 然后 说下 isEqual 和 isEqualToString 的区别 IsEqual 是 NSObj ...

  4. Window Server 2008 R2 TFS2010的安装和配置

    1.打开Setup进行安装 2.下一步,然后功能全选 3.点击安装,便开始安装了 安装成功 配置 进行配置之后,选择高级,因为其他功能可能没那么多 到如下界面后,直接进行下一步就可以 下一步,设置TF ...

  5. NEWS - InstallShield 2015 正式发布

    如果您需要为Windows®应用程序创建安装,InstallShield®便是您的最佳解决方案.在为桌面.服务器.云.Web和虚拟环境构建可靠的Windows Installer (MSI)和Inst ...

  6. GTD时间管理(1)---捕获搜集

    前一段时间感觉自己的整个思路很混乱,每一天觉得自己有很多事情很多,但是坐着做着不知道自己做了多少,做项目的时候做着做着时常东想西想.我个人觉得这种想法是不对经的. 于是在google上都出去寻找这方面 ...

  7. 更改ubuntu mysql data目录位置

    很多时候,mysql的数据会非常大,数据默认放在/var/lib/mysql,由于/var所划分的空间不够大,所以我们需要将mysql数据存放路径修改一下,放到大分区里面,以便可以应付mysql数据增 ...

  8. Swift 关键字汇总

    常见的关键字有以下4种 与声明有关的关键字:class.deinit.enum.extension.func.import.init.let.protocol.static.struct.subscr ...

  9. MVC4研发中遇到问题【持续总结....】

    第一: 编译器错误消息: CS0012: 类型“System.Data.Objects.DataClasses.EntityObject”在未被引用的程序集中定义.必须添加对程序集 “System.D ...

  10. PowerShell读取Windows产品密钥

    之前大多数人可能用过VBS读取Windows产品密钥的VBS脚本,VBS脚本通常都比较隐晦.难懂,今天忙里偷闲,随手写了一个用于读取Windows产品密钥的PowerShell脚本. 代码如下: == ...