【问题标题】:C# = Why are Excel processes not ending?C# = 为什么 Excel 进程没有结束?
【发布时间】:2011-04-01 12:25:15
【问题描述】:

我有以下代码:

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。我知道那里有重复的代码....很快就会整理出来:)

【问题讨论】:

标签: c# interop


【解决方案1】:

当您完成处理或正在做的任何事情时使用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();
   }
}

【讨论】:

  • 完美 - 谢谢。我曾尝试过,但在释放 comobjects 之后,它当然抛出了异常。在发布之前使用它很有魅力。
  • 如果用户打开 Excel 然后启动应用程序,那当然是非常粗鲁的...
  • @Lasse V. Karlsen:当他进入他的方法时,他可以用这行代码检查是否已经有任何正在运行的 excel:System.Diagnostics.Process.GetProcessesByName("excel").Length > 0,然后在方法退出时他可以选择不调用 Quit。
【解决方案2】:

我的解决方案

[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】:

    几天前我已经实施了导出/导入。 当我在谷歌上搜索时,我从某个地方得到了下面的代码,它工作正常。

    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 { }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-03
      • 1970-01-01
      • 2018-12-01
      • 2016-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多