我正在尝试关闭我的winform应用程序中的excel进程。我已经在so和其他网站上浏览了很多帖子,这就是我现在正在做的事情:
private void lsvSelectedQ_SelectedIndexChanged(object sender, EventArgs e)
{
FillSelectedItems();
}
private void FillSelectedItems()
{
string filepath = string.Empty;
string reportname = lblreportname.Text;
filepath = Application.StartupPath + "\\StandardReports\\" + reportname + ".xls";
Microsoft.Office.Interop.Excel.Application xlApp;
Microsoft.Office.Interop.Excel.Workbook xlWorkBook;
Microsoft.Office.Interop.Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
xlApp = new Microsoft.Office.Interop.Excel.Application();
xlWorkBook = xlApp.Workbooks.Open(filepath, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
List<string> WorksheetList = new List<string>();
xlWorkSheet = (Microsoft.Office.Interop.Excel.Worksheet)xlWorkBook.Worksheets.get_Item("Config");
Microsoft.Office.Interop.Excel.Range objRange = null;
objRange = (Microsoft.Office.Interop.Excel.Range)xlWorkSheet.Cells[6, 2];
if (objRange.Value != null)
{
int intSheet = Convert.ToInt32(objRange.Value);
for (int i = 0; i < intSheet; i++)
{
objRange = (Microsoft.Office.Interop.Excel.Range)xlWorkSheet.Cells[6, 3+i ];
if (objRange.Value != null)
{
lsvSelectedQ.Items.Add(Convert.ToString(objRange.Value));
}
}
}
ReleaseMyExcelsObjects(xlApp, xlWorkBook, xlWorkSheet);
}
在上面的代码中,我使用ReleaseMyExcelsObjects
方法来摆脱在任务栏中运行excel进程。
private void ReleaseMyExcelsObjects(Microsoft.Office.Interop.Excel.Application xlApp, Microsoft.Office.Interop.Excel.Workbook xlWorkBook, Microsoft.Office.Interop.Excel.Worksheet xlWorkSheet)
{
xlApp.DisplayAlerts = false;
xlWorkBook.Save();
xlWorkBook.Close();
xlApp.DisplayAlerts = false;
xlApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWorkSheet);
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWorkBook);
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);
xlWorkSheet = null;
xlWorkBook = null;
xlApp = null;
GC.Collect();
}
正如您所看到的,我在SelectedIndexChanged
上打开了一个excel,并且我还尝试通过ReleaseMyExcelsObjects()
方法关闭该进程,除了生成的第一个excel进程外,它工作正常。我的意思是,当事件被激发时,excel进程被启动,ReleaseMyExcelsObjects()
不会关闭它,但第二次激发SelectedIndexChanged
时,另一个excel进程启动。这次ReleaseMyExcelsObjects()
关闭了第二个excel进程。但是第一次触发SelectedIndexChanged事件时启动的第一个excel进程从未关闭。
- 编辑:**
我自己已经贴出了一个答案,这是完成工作。但我会保持这个问题开放,如果万一有人想出更好的解决方案。
3条答案
按热度按时间nvbavucw1#
我有一个关闭Excel进程的解决方案。与其经历释放对象的痛苦,你可以杀死特定的Excel进程(如果你有多个打开的进程)。代码是:
你可以这样称呼它:
YourNameSpace.MicrosoftApplications.Excel xlApp = new YourNameSpace.MicrosoftApplications.Excel();
通过调用
xlApp.Application.whatever
而不是xlApp.whatever
来完成任何需要做的事情,如果用户退出excel窗口,它将杀死代码中使用的进程。如果您只想在后台生成一个报告,但不显示表单,那么只需调用xlApp.Kill();
来结束该特定进程。rks48beu2#
我已经找到了一个解决办法:
将其用作
classobj.GetExcelProcess(xlApp).Kill();
摘自:https://stackoverflow.com/a/15556843/2064292
b91juud33#
据我所知,ReleaseComObject会在您的C#应用程序退出时关闭Excel应用程序。因此,每次您调用FillSelectedItems()时,新的Excel进程都会显示在您的任务栏中,直到您退出C#应用程序时才会关闭。
编辑:在一个侧记,我建议使用尝试,捕捉,最后当处理Excel互操作库,主要是由于这样一个事实,即如果应用程序运行到一个异常,该程序将不会正常退出,并如前所述,它会导致Excel进程留在任务栏中(当您手动打开Excel上说的文件,它会告诉你最后一次恢复的版本blablabla)
老实说,如果你对此感到恼火,我建议你使用EPPlus或ExcelDataReader(这个只用于阅读Excel电子表格)作为替代库,否则,无论你添加多少releaseComObjects或garbagecollector,我相信你都无法摆脱这个问题。
编辑2:当然,另一种解决方法是搜索Excel进程ID并将其删除。我不建议这样做的原因是,如果运行此应用程序的用户已经在其计算机上运行了另一个Excel进程,则可能最终会删除该示例。