调用 Word.Documents.Add 后 WinWord.exe 不会退出 - Word .NET Interop

2024-04-30

我遇到了一个经典场景,即在 .NET 中创建 Word COM 对象(通过 Microsoft.Office.Interop.Word 程序集)时,WinWord 进程不会退出,即使我正确关闭和释放物体 http://www.xtremevbtalk.com/showthread.php?p=1326018.

我已将范围缩小到使用 Word.Documents.Add() 方法。我可以以其他方式使用 Word,不会出现任何问题(打开文档、修改内容等),并且当我告诉 WinWord.exe 退出时,它就会退出。有一次我使用 Add() 方法(并且仅在添加template)该进程保持运行状态。

这是一个重现该问题的简单示例:

Dim word As New Word.Application()
word.Visible = False

Dim documents As Word.Documents = word.Documents
Dim doc As Word.Document = documents.Add(Template:=CObj(templatePath), NewTemplate:=False, DocumentType:=Word.WdNewDocumentType.wdNewBlankDocument, Visible:=False)

'' dispose objects
doc.Close()
While (Marshal.ReleaseComObject(doc) <> 0)
End While
doc = Nothing

While (Marshal.ReleaseComObject(documents) <> 0)
End While
documents = Nothing

word.Quit()
While (Marshal.ReleaseComObject(word) <> 0)
End While
word = Nothing

GC.Collect()

正如您所看到的,我正在正确创建和处置对象,甚至采取额外的步骤来循环 Marsha.ReleaseComObject 直到它返回正确的代码。使用 Word 对象在其他方面都很好,只是令人讨厌的 Documents.Add 让我感到悲伤。在此过程中是否创建了另一个我需要引用和处置的对象?我还需要遵循其他处置步骤吗?还有别的事吗?非常感谢您的帮助 :)

Update:我在处置步骤结束时尝试了 GC.Collect 但仍然没有运气。

Update 2:我已将问题范围缩小到使用自定义模板。当我调用 Documents.Add(...) 时,我为新文档指定一个自定义模板。如果我不这样做,而是调用不带参数的 Add(),那么问题就不会发生。


(我的所有建议均改编自这个答案 https://stackoverflow.com/questions/158706/#158752关于 Excel 互操作。)

这里有一些重要的事情:

1) 切勿在同一行上使用 2 个点。还可以将索引器视为点

Good

Word.Documents d = wordApp.Documents;
Word.Document aDoc = d.Open(/*...*/);

BAD

Word.Document aDoc = wordApp.Documents.Open(/*...*/);

2) 释放所有指针。

3)不,真的,返回并释放所有的指针,你在某个地方错过了一个(或者至少我总是这样做)。

这是一个完整的例子,展示了在我痛苦地哀嚎和咬牙切齿之后,最终在一个项目上为我工作的内容:

object m = Missing.Value;
// this must be an object, not a string. if you forget though,
// intellisense will remind you
object oFilename = @"C:\my sheet.doc";

object readOnly = false;
object isVisible = false;

Word.Application wordApp = new Word.ApplicationClass();
wordApp.Visible = false;
// remember: don't use 2 dots on 1 line
Word.Documents d = wordApp.Documents;
Word.Document aDoc = d.Open(ref oFilename, ref m, ref readOnly, ref m,
    ref m, ref m, ref m, ref m, ref m, ref m, ref m, ref isVisible,
    ref m, ref m, ref m, ref m);
aDoc.Activate();

object findText = "my old value";
object replaceText = "new and improved value";

object oTrue = true;
object oFalse = false;
object replace = 2;
object wrap = 1;

Word.Selection s = wordApp.Selection;
Word.Find f = s.Find;
f.Execute(ref findText, ref oTrue,
    ref oTrue, ref oFalse, ref oFalse,
    ref oFalse, ref oTrue, ref wrap, ref oFalse,
    ref replaceText, ref replace, ref oFalse, ref oFalse,
    ref oFalse, ref oFalse);

aDoc.SaveAs(ref oFilename, ref m, ref m, ref m, ref m, ref m, ref m,
    ref m, ref m, ref m, ref m, ref m, ref m, ref m, ref m, ref m);

object doNotSaveChanges = Word.WdSaveOptions.wdDoNotSaveChanges;
// casting here because intellisense complained of ambiguity
(aDoc as Word._Document).Close(ref doNotSaveChanges, ref m, ref m);

// release each in the reverse of the order in which it was first used
// ReleaseComObject might also work as well. I haven't tested yet
Marshal.FinalReleaseComObject(f);
Marshal.FinalReleaseComObject(s);
Marshal.FinalReleaseComObject(aDoc);
Marshal.FinalReleaseComObject(d);

// must quit app before releasing
// again: casting because intellisense complained of ambiguity
(wordApp as Word._Application).Quit(ref m, ref m, ref m);
Marshal.FinalReleaseComObject(wordApp);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

调用 Word.Documents.Add 后 WinWord.exe 不会退出 - Word .NET Interop 的相关文章

  • 等待 IAsyncResult 函数直至完成

    我需要创建等待 IAsyncResult 方法完成的机制 我怎样才能做到这一点 IAsyncResult result contactGroupServices BeginDeleteContact contactToRemove Uri
  • SqlCommand.Dispose() 在 SqlTransaction.Commit() 之前?

    在提交事务之前处理分配给事务的命令是否有效 我自己测试了以下代码 它似乎工作得很好 但这是一个相当小的例子 所以我正在寻找是否有人确实知道的确认 internal static void TestTransaction try Progra
  • .NET 标准与 .NET 核心

    我已经了解了 NET Standard 和 NET Core 之间的区别 但我真的不知道区别是什么 或者何时选择 NET Standard 库项目以及何时选择 NET Core 库项目 我读到 NET Standard 是为了确保一组 AP
  • 如何将 Razor 视图转换为字符串?

    我想使用我的 Razor 视图作为某种发送电子邮件的模板 所以我想将我的模板 保存 在视图中 将其作为字符串读入控制器 进行一些必要的替换 然后发送它 我有有效的解决方案 我的模板作为 HTML 页面托管在某处 但我想将其放入我的应用程序中
  • ASP.NET MVC:如何可靠地获取当前请求的真实URL?

    现在我有一个 MVC 应用程序运行在http 127 0 0 1 8081 http 127 0 0 1 8081 它实际上在 Azure 计算模拟器中运行 浏览器位置栏清楚地显示端口号为 8081 然而 Request Url and R
  • 如何判断应用程序是否是Web应用程序

    在 Windows 服务和 Web 应用程序中运行的核心程序集中 我需要存储每个用户会话的信息 该服务将具有单个用户会话 并且 Web 应用程序使用 HttpContext Current 我想配置在核心程序集中使用哪种方法 约定优于配置
  • 什么是扩展方法?

    NET 中的扩展方法是什么 编辑 我已在以下位置发布了后续问题扩展方法的使用 https stackoverflow com questions 403619 usage of extension methods 扩展方法允许开发者向公众添
  • 面向对象的铸造错误[重复]

    这个问题在这里已经有答案了 将派生类强制转换为基类 我有一个通用的基本抽象类 继承自 IComparable 其定义如下 public abstract class BaseClass
  • 如何创建可以像 UserControl 一样编辑的 TabPage 子类?

    我想创建一个包含一些控件的 TabPage 子类 并且我想通过设计器来控制这些控件的布局和属性 但是 如果我在设计器中打开子类 我将无法像在 UserControl 上那样定位它们 我不想创建一个带有 UserControl 实例的 Tab
  • 为什么要序列化对象需要 Serialized 属性

    根据我的理解 SerializedAttribute 不提供编译时检查 因为它都是在运行时完成的 如果是这样 那么为什么需要将类标记为可序列化呢 难道序列化器不能尝试序列化一个对象然后失败吗 这不就是它现在所做的吗 当某些东西被标记时 它会
  • 在资源字典中添加字体系列

    我正在使用msdn教程 http msdn microsoft com en us library ms753303 aspx wa wsignin1 0要在我的 Wpf 应用程序中添加 FontFamily 在 csproj 中我有
  • smtpclient“发送邮件失败”

    这是我的代码 for int i 0 i lt number i MailAddress to new MailAddress iMail to MailAddress from new MailAddress iMail from iMa
  • 更改组合框下拉列表边框的颜色

    My code Private Sub ComboBox2 DrawItem sender As Object e As DrawItemEventArgs Handles ComboBox2 DrawItem If e Index lt
  • 将对象列表添加到 ef 中的上下文

    是否可以在不使用 foreach addObject 的情况下将对象列表添加到实体框架中的 Context 感谢帮助 从 EntityFramework 6 开始 您可以使用DbSet AddRange 方法 IEnumerable htt
  • 为什么我的 DLL 无法注册?

    我正在 VS2005 中构建一个项目 但我的几个 DLL 无法注册 我在 Visual Studio 中收到的错误消息是 项目 错误 PRJ0019 工具从 注册 ActiveX 控件 返回错误代码 这很模糊 当我通过命令行手动注册DLL时
  • 在 .NET 并发线程之间传递数据的最佳方式是什么?

    我有两个线程 一个需要轮询一堆单独的静态资源以查找更新 另一种需要获取数据并将其存储在数据库中 线程1如何告诉线程2有东西要处理 如果数据块是独立的 则将数据块视为要由线程池处理的工作项 使用线程池和QueueUserWorkItem将数据
  • DLL 中的 GUID (.Net)

    我在这方面不是很有经验 所以我有几个问题 首先 所有 Net 创建的 DLL 是否都有自己的 GUID 如果没有 我的问题是如何获得一个并将其与 DLL 关联 那么问题是 我如何获得该 dll 的 GUID 即 给定 DLL 路径 c so
  • 如何打开带有预填充附件的 Outlook 新邮件窗口

    当用户单击我的应用程序中的某些按钮或链接时 我需要打开一个带有预填充附件的新电子邮件窗口 老问题 但我也遇到了这个问题 所以这里有一个复制和粘贴解决方案 Microsoft Office Interop Outlook Applicatio
  • 将日期时间转换为指定格式

    我有这个日期格式yy MM dd HH mm ss ex 12 02 21 10 56 09 问题是 当我尝试使用以下代码将其转换为不同格式时 CDate 12 02 21 10 56 09 ToString MMM dd yyyy HH
  • 如何使用 Roslyn 通过扩展方法、静态类中的方法以及带有 ref/out 参数的方法来访问调用

    我正在致力于创建一个开源项目 用于创建 NET UML 序列图 该项目利用名为 js sequence diagrams 的 javascript 库 我不确定 Roslyn 是适合这项工作的工具 但我想我应该尝试一下 所以我整理了一些概念

随机推荐