问题 C#=为什么Excel进程没有结束?


我有以下代码:

private bool IsMousetrapFile(string path)
    {

        logger.Log(validateFileMessage + path);

        Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
        Excel.Workbooks workbooks = xlApp.Workbooks;
        Excel.Workbook xlWorkBook = workbooks.Open(path, Type.Missing, Type.Missing,
            Type.Missing, Type.Missing, Type.Missing,
            Type.Missing, Type.Missing, Type.Missing, Type.Missing,
            Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
        Excel.Sheets worksheets = (Excel.Sheets)xlWorkBook.Worksheets;
        Excel.Worksheet ws = null;


        foreach (string sheet in expectedWorksheets)
        {

            try
            {

                ws = (Excel.Worksheet)worksheets.get_Item(sheet);
                logger.Log(validMousetrapFileMessage + path);
            }
            catch
            {
                logger.Log(validateSheetError + sheet + ": " + path);
                if (ws != null)
                    Marshal.ReleaseComObject(ws);
                Marshal.ReleaseComObject(worksheets);
                Marshal.ReleaseComObject(xlWorkBook);
                Marshal.ReleaseComObject(workbooks);
                Marshal.ReleaseComObject(xlApp);

                return false;

            }

        }

        if (ws != null)
            Marshal.ReleaseComObject(ws);
        Marshal.ReleaseComObject(worksheets);
        Marshal.ReleaseComObject(xlWorkBook);
        Marshal.ReleaseComObject(workbooks);
        Marshal.ReleaseComObject(xlApp);

        return true;


    }

实际上,它会检查Excel工作簿是否包含特定工作表。无论是否存在,我都希望Excel流程结束。但是,每次打开新工作簿时,都会添加一个新进程,并且永远不会删除?

PS。我知道那里有重复的代码....它应该很快整理:)


5754
2018-04-01 12:25


起源

这就像你问的那样: stackoverflow.com/questions/5357244/... - gideon
有关详细信息,请参阅链接,了解当您调用quit时excel仍然运行的时间。 - gideon


答案:


使用 Excel.Application.Quit() 当你完成处理或你正在做的任何事情。

在你的情况下: xlApp.Quit();

更新:

@Lasse V. Karlsen 指出如果Excel已经运行该怎么办。好吧,这是一个解决方案:(我没有测试代码,这只是为了给你一个想法)

private void TestMethod()
{
   bool excelWasRunning = System.Diagnostics.Process.GetProcessesByName("excel").Length > 0;

   // your code

   if (!excelWasRunning)
   { 
       xlApp.Quit();
   }
}

10
2018-04-01 12:28



很好,谢谢。我曾经尝试过,但是在释放comobject之后,当然它抛出了异常。在发布之前使用它的魅力。 - Darren Young
@Darren Young:gr8 - HABJAN
如果用户打开Excel然后启动应用程序,这当然是非常粗鲁的... - Lasse Vågsæther Karlsen
@Lasse V. Karlsen:当他输入他的方法时,他可以检查是否已经有这行代码运行excel:System.Diagnostics.Process.GetProcessesByName(“excel”)。Length> 0,然后在方法退出时他可以选择不打电话退出。 - HABJAN


我的解决方案

[DllImport("user32.dll")]
static extern int GetWindowThreadProcessId(int hWnd, out int lpdwProcessId);

private void GenerateExcel()
{
    var excel = new Microsoft.Office.Interop.Excel.Application();
    int id;
    // Find the Process Id
    GetWindowThreadProcessId(excel.Hwnd, out id);
    Process excelProcess = Process.GetProcessById(id);

try
            {
                // Your code
}
finally
{
    excel.Quit();

    // Kill him !
    excelProcess.Kill();
}

3
2018-06-18 09:19





几天前我实施了出口/进口。 当我在谷歌搜索时,我从某个地方得到了以下代码,它运行正常。

ExportToExcel()
{
    try
    {
        //your code
    }
   catch (Exception ex)
        {

        }
        finally
        {
            TryQuitExcel(Application_object);
        }
}
private static void TryQuitExcel(Microsoft.Office.Interop.Excel.Application  application)
        {
            try
            {
                if (application != null &&
                  application.Workbooks != null &&
                  application.Workbooks.Count < 2)
                {
                    application.DisplayAlerts = false;
                    application.Quit();
                    Kill(application.Hwnd);
                    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(application);
                    application = null;
                }
            }
            catch
            {
                /// Excel may have been closed via Windows Task Manager.
                /// Skip the close.
            }
        }


 private static void Kill(int hwnd)
    {
        int excelPID = 0;
        int handle = hwnd;
        GetWindowThreadProcessId(handle, ref excelPID);

        Process process = null;
        try
        {
            process = Process.GetProcessById(excelPID);

            //
            // If we found a matching Excel proceess with no main window
            // associated main window, kill it.
            //
            if (process != null)
            {
                if (process.ProcessName.ToUpper() == "EXCEL" && !process.HasExited)
                    process.Kill();
            }
        }
        catch { }
    }

1
2018-04-01 12:48