处置Microsoft.Office.Interop.Word.Application

时间:2011-07-21 14:11:36

标签: c# interop automation 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();

我正在尝试以编程方式打开并打印文件。

问题是每次运行上面的代码时都会启动一个新的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);

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

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

7 个答案:

答案 0 :(得分:50)

您是否需要致电Quit

app.Quit();

答案 1 :(得分:40)

也许尝试设置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!
}

答案 2 :(得分:2)

您需要调用app.Quit()来关闭应用程序。我使用下面的代码&它对我来说就像一个魅力 -

try
{
   Microsoft.Office.Interop.Word.Application wordApp = new Microsoft.Office.Interop.Word.Application();
   wordApp.Visible = false;
   Microsoft.Office.Interop.Word.Document doc = null;

   //Your code here...

   doc.Close(false); // Close the Word Document.
   wordApp.Quit(false); // Close Word Application.
}
catch (Exception ex)
{
   MessageBox.Show(ex.Message + "     " + ex.InnerException);
}
finally
{
   // Release all Interop objects.
   if (doc != null)
      System.Runtime.InteropServices.Marshal.ReleaseComObject(doc);
   if (wordApp != null)
      System.Runtime.InteropServices.Marshal.ReleaseComObject(wordApp);
   doc = null;
   wordApp = null;
   GC.Collect();
}

答案 3 :(得分:1)

试试这个..

doc.Close(false);
app.Quit(false);
if (doc != null)
    System.Runtime.InteropServices.Marshal.ReleaseComObject(doc);
if (app != null)
    System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
doc = null;
app = null;
GC.Collect();

答案 4 :(得分:1)

我认为主要问题(似乎没有人注意到)是,如果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();
}

答案 5 :(得分:0)

我关闭文档,然后关闭适用于我的应用程序,然后强制进行垃圾回收。

// Document
object saveOptionsObject = saveDocument ? Word.WdSaveOptions.wdSaveChanges : Word.WdSaveOptions.wdDoNotSaveChanges;
this.WordDocument.Close(ref saveOptionsObject, ref Missing.Value, ref Missing.Value);

// Application
object saveOptionsObject = Word.WdSaveOptions.wdDoNotSaveChanges;
this.WordApplication.Quit(ref saveOptionsObject, ref Missing.Value, ref Missing.Value); 

GC.Collect();
GC.WaitForPendingFinalizers();

答案 6 :(得分:0)

与其他海报达成协议,不需要GC.Collect()Marshal.ReleaseComObject()。如果在运行app.Quit(false)之后该进程仍然存在,则可能是因为您在不可见的情况下运行该应用程序,并且出现了阻止该应用程序关闭的提示,例如“文档恢复”对话框。在这种情况下,您需要在创建应用程序时添加它。

app.DisplayAlerts = false;