如何保证MS Word进程退出(使用C#Interop库)?
我目前的做法:
// close word document ("doc")
((_Document)doc).Close(SaveChanges: WdSaveOptions.wdDoNotSaveChanges);
if (doc != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(doc);
doc = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
// close word application ("word")
((_Application)word).Quit(false);
if (word != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(word);
word = null;
GC.Collect();
GC.WaitForPendingFinalizers();
}
// and here is how it fails
Process[] pname = Process.GetProcessesByName("WINWORD");
Assert.IsTrue(pname.Length == 0);
来源:
c# MSOffice Interop Word will not kill winword.exe
Disposing of Microsoft.Office.Interop.Word.Application
Microsoft.Interop object won't quit or "release"
答案 0 :(得分:0)
如果使用GC方法滑动堆,则无需使用ReleaseComObject。另外请注意,您需要两次调用GC方法:
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
无论如何,我总是建议使用System.Runtime.InteropServices.Marshal.ReleaseComObject来释放Office(Word)对象。然后在Visual Basic中将变量设置为Nothing(C#中为null)以释放对该对象的引用。您可以在Systematically Releasing Objects文章中详细了解相关内容。它与Outlook有关,但相同的规则可以应用于任何Office应用程序(包括Word)。
答案 1 :(得分:0)
无论如何对我来说都是工作
Word.Application app = null;
Word.Document doc = null;
Word.Tables tables = null;
Word.ContentControls mainControls = null;
try
{
app = new Word.Application();
app.ScreenUpdating = false;
app.Visible = false;
app.DisplayAlerts = Word.WdAlertLevel.wdAlertsNone;
doc = app.Documents.Open(fileName);
tables = doc.Tables;
//.. my code
if (tables.Count < 1)
val = mainControls[2].Range.Text ?? "";
//end of my code
}
catch (Exception exc) { G.log(exc); }
finally
{
//CLEAN UP
GC.Collect();
GC.WaitForPendingFinalizers();
if (mainControls != null)
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(mainControls);
if (tables != null)
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(tables);
if (doc != null)
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(doc);
app.Quit();
if (app != null)
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(app);
}