处置Microsoft.Office.Interop.Word.Application

Max*_*ich 37 c# automation interop office-interop

(从帖子中得到一些后续内容(仍然没有答案):https://stackoverflow.com/q/6197829/314661)

使用以下代码

Application app = new Application();
_Document doc = app.Documents.Open("myDocPath.docx", false, false, false);
doc.PrintOut(false);
doc.Close();
Run Code Online (Sandbox Code Playgroud)

我试图以编程方式打开并打印文件.

问题是每次运行上面的代码时都会启动一个新的WINWORD.exe进程,很明显这会很快占用所有内存.

应用程序类似乎不包含dispose/close或类似方法.

经过一番研究后我(实现了)并将代码更改为以下内容.

 Application app = new Application();
 _Document doc = app.Documents.Open(fullFilePath + ".doc", false, false, false);
 doc.PrintOut(false);
 doc.Close();
 int res = System.Runtime.InteropServices.Marshal.ReleaseComObject(doc);
 int res1 = System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
Run Code Online (Sandbox Code Playgroud)

我可以看到剩余的引用计数为零,但过程仍然存在?

PS:我正在使用Microsoft.Office.Interop库的第14版.

Eni*_*ity 51

你不需要打电话Quit吗?

app.Quit();
Run Code Online (Sandbox Code Playgroud)


Nic*_*ick 41

也许尝试设置doc = null和调用GC.Collect()

编辑,而不是我自己的代码,我忘记了我得到它的地方,但这是我用来处理Excel的东西,它可以完成工作,也许你可以从中收集一些东西:

public void DisposeExcelInstance()
{
    app.DisplayAlerts = false;
    workBook.Close(null, null, null);
    app.Workbooks.Close();
    app.Quit();
    if (workSheet != null)
        System.Runtime.InteropServices.Marshal.ReleaseComObject(workSheet);
    if (workBook != null)
        System.Runtime.InteropServices.Marshal.ReleaseComObject(workBook);
    if (app != null)
        System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
    workSheet = null;
    workBook = null;
    app = null;
    GC.Collect(); // force final cleanup!
}
Run Code Online (Sandbox Code Playgroud)

  • 绝对的腿和.App.Quit()是关键......谢谢! (12认同)
  • GC.Collect()就像Betelgeuse:你必须调用它三次才能以任何可观察的方式作出回应. (4认同)
  • 如果关闭文档并退出应用程序,则不需要`GC.Collect()`或`Marshal.ReleaseComObject()` (3认同)

小智 5

最好的解决方案..最后:

try {

    Microsoft.Office.Interop.Word.Application appWord = new Microsoft.Office.Interop.Word.Application();
    appWord.Visible = false;
    Microsoft.Office.Interop.Word.Document doc = null;
    wordDocument = appWord.Documents.Open((INP), ReadOnly: true);

    wordDocument.ExportAsFixedFormat(OUTP, Microsoft.Office.Interop.Word.WdExportFormat.wdExportFormatPDF);

    // doc.Close(false); // Close the Word Document.
    appWord.Quit(false); // Close Word Application.
} catch (Exception ex) {
    Console.WriteLine(ex.Message + "     " + ex.InnerException);
}
Run Code Online (Sandbox Code Playgroud)


小智 5

我认为似乎没有人注意到的主要问题是,如果 Word 已经打开,您不应该首先创建新的 Application 对象。我们这些从 COM 和/或 VB6 时代就开始编码的人会记得 GetActiveObject。幸运的是 .Net 只需要一个 ProgID。

推荐的方法如下:

try
{
    wordApp = (word.Application) Marshal.GetActiveObject("Word.Application");
}
catch(COMException ex) when (ex.HResult == -2147221021)
{
    wordApp = new word.Application();
}
Run Code Online (Sandbox Code Playgroud)