为什么Microsoft.Office.Interop.Excel.Application.Quit()会使后台进程运行?

下面的代码留下一个Microsoft Excel后台进程运行,直到我的程序退出后:

var excelApplication = new Application(); var workbooks = excelApplication.Workbooks; var workbook = excelApplication.Workbooks.Open(file.FullName); workbook.Close(); excelApplication.Workbooks.Close(); excelApplication.Quit(); Marshal.ReleaseComObject(workbook); Marshal.ReleaseComObject(workbooks); Marshal.ReleaseComObject(excelApplication); 

为什么? 我错过了什么?

得到它了!

application.Workbooks!= application.Workbooks

这个属性不公开一个variables,它会生成一个值。 所以每次访问工作簿属性时,我都会创build一个新的COM对象。

我修正了代码,一切都很好。 谢谢大家。

 var excelApplication = new Application(); var workbooks = excelApplication.Workbooks; var workbook = workbooks.Open(pathToExcelWorkbook); // Fixed workbook.Close(); workbooks.Close(); excelApplication.Quit(); Marshal.ReleaseComObject(workbook); Marshal.ReleaseComObject(workbooks); Marshal.ReleaseComObject(excelApplication); 

这是Office应用程序广泛分布的问题。 所有的Excel加载项/自动化应用程序应该在不再需要时系统地释放它们对Excel对象的引用。 未能系统地释放对Excel对象的引用可能会阻止Microsoft Office Excel正确closures。 请参阅系统地释放对象以获取更多信息。 它与Outlook有关,但同样的原则可以应用于所有的Office应用程序。

使用System.Runtime.InteropServices.Marshal.ReleaseComObject完成使用时释放Excel对象。 然后在Visual Basic中将variables设置为Nothing(C#中为null)以释放对该对象的引用。

这是错误的 做法 ,但这是解决这个问题最简单的方法

  [DllImport("user32.dll")] private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); private Application _excelApp; private Workbook _excelWorkBook; private Worksheet _excelSheet; private void CloseExcelApp() { int hWnd = _excelApp.Application.Hwnd; uint processID; GetWindowThreadProcessId((IntPtr)hWnd, out processID); Process.GetProcessById((int)processID).Kill(); _excelWorkBook = null; _excelApp = null; _excelSheet = null; } 

所有你需要的是当你需要使用它时,初始化所有未初始化的variables,并在需要closures应用程序时调用CloseExcelApp()。