症状

在使用.net调用 Microsoft Office 应用程序时,Office 应用程序在调用Quit方法时不会退出。

原因

Visual Studio.NET 从托管代码调用 COM 对象时,它会自动创建运行时可调用包装 (RCW)。RCW 将.NET 应用程序和 COM 对象之间的调用封送。RCW 保持该 COM 对象上的引用计数。因此,如果尚未释放 RCW 上的所有引用,COM 对象不会退出。

解决方案

若要确保 Office 应用程序将退出,确保自动化代码满足以下条件:

  • 将每个对象声明为新变量。例如,将下面的代码行的更改

    oBook = oExcel.Workbooks.Add()			

    更改后:

    dim oBooks as Excel.Workbooks
    oBooks = oExcel.Workbooks
    oBook = oBooks.Add()
  • 在循环中使用System.Runtime.InteropServices.Marshal.ReleaseComObject ,直到完成后使用的对象,则返回 0。System.Runtime.InteropServices.Marshal.ReleaseComObject递减 RCW,而该环路的引用计数将确保不管如何释放基础 COM 组件很多时候它已重新进入 CLR。
  • 若要解除对变量的引用,设置为空值空值的变量等。
  • 使用 Office 应用程序对象的Quit方法告诉服务器关闭。

示例

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim oApp As New Excel.Application()
Dim oBooks As Excel.Workbooks = oApp.Workbooks
Dim oBook As Excel.Workbook = oBooks.Add
Dim oSheet As Excel.Worksheet = oApp.ActiveSheet NAR(oSheet)
oBook.Close(False)
NAR(oBook)
NAR(oBooks)
oApp.Quit()
NAR(oApp) Debug.WriteLine("Sleeping...")
System.Threading.Thread.Sleep(5000)
Debug.WriteLine("End Excel")
End Sub Private Sub NAR(ByVal o As Object)
Try
While (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0)
End While
Catch
Finally
o = Nothing
End Try
End Sub

 如果您使用的 Visual C#.NET,引用NAR()函数的代码:

private void NAR(object o)
{
try
{
while (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > ) ;
}
catch {}
finally
{
o = null;
}
}

注:从开始.NET Framework 2.0,您可以使用System.Runtime.InteropServices.Marshal.FinalReleaseComObject来代替 while 循环调用System.Runtime.InteropServices.Marshal.ReleaseComObject来实现相同的结果。

故障排除

请注意,如果您按照中所述的步骤"步骤重现行为"一节,并在服务器仍然没有关闭向下,您可以使用GC。Collect()方法和GC。WaitForPendingFinalizers()后释放的最后一个对象的方法。因为运行库对GC,RCW 执行垃圾回收。Collect()方法强制垃圾回收器在运行,并可能释放任何仍有 RCW 的引用。GC。Collect()方法尝试回收可用的最大内存。请注意,这不能保证所有内存都被都回收。

调用office COM出现不会退出的问题的更多相关文章

  1. .NET通过调用Office组件导出Word文档

    .NET通过调用Office组件导出Word文档 最近做项目需要实现一个客户端下载word表格的功能,该功能是用户点击"下载表格",服务端将该用户的数据查询出来并生成数据到Word ...

  2. .Net调用Office Com组件的原理及问题检索com类工厂组件检索 COM 类工厂中 CLSID 为 {XXX} 的组件失败

    我是在本地32位操作系统+vs2010+office2007做创建并下载Excel,ppt文件的操作没有问题,发布到64位系统的服务器上报错,最开始报错:: 1:Retrieving the COM ...

  3. ASP.NET调用Office Com组件权限设置

    ASP.NET在调用Office Com组件时,经常会出现权限限制的问题,而出现如下错误: 现通过以下几步设置,可解决上述问题:(1)64位系统中,请在IIS应用程序池集成模式中应启用调用32位应用程 ...

  4. Asp.Net调用Office组件操作时的DCOM配置 (转)

    Asp.Net调用Office组件操作时的DCOM配置 http://blog.csdn.net/gz775/article/details/6447758 在项目中将数据导出为Excel格式时出现“ ...

  5. Win2008服务启动不能调用Office Word的解决方法

    本文为大家分享一下如何解决Windows Server 2008 服务启动不能调用Office Word的问题,分享这个教程的原因是,今天在Windows server2008上部署一个应用时发现了一 ...

  6. SVG格式转Visio的vsd格式方法,附带C#动态调用Office的Com组件方法

    SVG格式可以直接显示在网页上面,用来实现诸如统计Chart图表.流程图.组织结构图的功能.为了使图像可以下载下来以便于修改,可以将SVG转为Visio的vsd格式.方法很简单,主要是使用Visio组 ...

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

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

  8. 解决调用Office组件的问题

    在修改一个之前工作的好好的工具的时候出了如下错误: 无法将类型为“System.__ComObject”的 COM 对象强制转换为接口类型“Microsoft.Office.Interop.Excel ...

  9. JAVA中调用外部程序,并等待其退出(涉及Runtime和ProcessBuilder)

    这段时间要写一个java调用外部程序的功能,踩了几个坑,这里分享一下. 首先用的是RunTime,调用代码如下: Process pro = Runtime.getRuntime().exec(&qu ...

随机推荐

  1. 【玩转Golang】beego下实现martini中的透明式静态文件服务(static folder)效果。

    出于效率等原因,最近将web框架由martini切换为了beego,其他地方都很平顺,只是两个框架的handler签名不一致,需要修改,所以耗时较长,这是预计到的.但是有一个地方没有预计到,也耗费了较 ...

  2. Thinkphp5笔记六:公共模块common的使用

    common模块属于公共模块,Thinkphp框架,默认就能调用. 实际用处:任何模块都可能用到的模型.控制.事件提取出来放到公共模块下. 一.公共事件  apps\common\common.php ...

  3. VBscript实现开机自动启动,自动复制原件后启动

    set fso = createobject("scripting.filesystemobject") set ws = createobject("wscript.s ...

  4. Linux同时安装python2和Python3

    我们以Ubuntu 为例,默认地,Linux安装好后会默认安装python2版本: 安装Python3: For Debian:   [user@host]$ sudo apt-get install ...

  5. 本地存储(LocalStorage、SessionStorage、Web SQL Database、Indexed DB)

    https://www.cnblogs.com/SeeYouBug/p/6127001.html https://blog.csdn.net/inter_peng/article/details/49 ...

  6. RESTEasy maven使用

    添加依赖: <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteas ...

  7. ios的单元測试OCUnit以及更新了之后的XCTestCase

    1.像一般创建项目的步骤一样.创建一个用于測试的项目或者打开一个待測试的项目. (oc是5.0之前所使用的測试,如今用的是XCtestCase,默认会创建一个主的測试类.曾经版本号可能非常多步骤省去) ...

  8. DOS 配置IP地址

    @echo off :startIP set /p source=STATIC Y or N or E: echo source:%source% if "%source%" == ...

  9. Burp Post、Get数据包转为上传multipart/form-data格式数据包

    方法一: 新建一个网页进行上传,代码代码如下: <html> <head></head> <body> <form method="po ...

  10. MongoDB(五)-- 副本集(replica Set)

    一.副本集介绍 搭建副本集是为了实现mongodb高可用. Mongodb(M)表示主节点,Mongodb(S)表示备节点,Mongodb(A)表示仲裁节点.主备节点存储数据,仲裁节点不存储数据.客户 ...