Excel process remains open after interop; traditional method not working

后端 未结 4 1449
鱼传尺愫
鱼传尺愫 2021-01-05 02:39

I\'m running into an issue with some code I\'m debugging. Excel interop is used to extract some values from a workbook; however, Excel remains open after the program has exi

相关标签:
4条回答
  • 2021-01-05 02:43

    This is how I got around this problem:

    // Store the Excel processes before opening.
    Process[] processesBefore = Process.GetProcessesByName("excel");
    
    // Open the file in Excel.
    Application excelApplication = new Application();
    Workbook excelWorkbook = excelApplication.Workbooks.Open(Filename);
    
    // Get Excel processes after opening the file.
    Process[] processesAfter = Process.GetProcessesByName("excel");
    
    // Now find the process id that was created, and store it.
    int processID = 0;
    foreach (Process process in processesAfter)
    {
        if (!processesBefore.Select(p => p.Id).Contains(process.Id))
        {
            processID = process.Id;
        }
    }
    
    // Do the Excel stuff
    
    // Now close the file with the COM object.
    excelWorkbook.Close();
    excelApplication.Workbooks.Close();
    excelApplication.Quit();
    
    // And now kill the process.
    if (processID != 0)
    {
        Process process = Process.GetProcessById(processID);
        process.Kill();
    }
    
    0 讨论(0)
  • 2021-01-05 02:49

    This code works for me.

    //Declare separate object variables
    Excel.Application xlApp = new Excel.Application();
    Excel.Workbooks xlWorkbooks = xlApp.Workbooks;
    Excel.Workbook xlWorkbook = xlWorkbooks.Add(Missing.Value);
    Excel.Worksheet xlWorksheet = (Excel.Worksheet)xlWorkbook.Worksheets.get_Item(1);
    
    //Create worksheet
    
    xlWorkbook.Close(false, Missing.Value, Missing.Value);
    xlWorkbooks.Close();
    xlApp.Quit();
    
    Marshal.FinalReleaseComObject(xlWorksheet);
    Marshal.FinalReleaseComObject(xlWorkbook);
    Marshal.FinalReleaseComObject(xlWorkbooks);
    Marshal.FinalReleaseComObject(xlApp);
    
    xlWorksheet = null;
    xlWorkbook = null;
    xlWorkbooks = null;
    xlApp = null;
    
    GC.Collect();
    

    This article from Microsoft has some good information regarding this issue.

    0 讨论(0)
  • 2021-01-05 02:57

    I am a total COM amateur, used it for a minor thing in one project quite a long time ago, but here's a snippet I used there. I probably found it somewhere online, don't remember. In any case, I paste it its full glory ;)

    public static class ComBlackBox
    {
        public static void ReleaseObject(object obj)
        {
            try
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
                obj = null;
            }
            catch (ArgumentException ex)
            {
                obj = null;
                MessageBox.Show("Unable to release the Object " + ex.Message);
            }
            finally
            {
                GC.Collect();
            }
        } 
    }
    

    I'm unable to try it out now, but it probably worked (I honestly don't remember any details). Maybe it will help you out. Feel free to point out any obvious problems with this code, I really am far from being COM-literate ;)

    0 讨论(0)
  • 2021-01-05 03:01

    This has worked successfully for me:

            xlApp.Quit();
    
            //release all memory - stop EXCEL.exe from hanging around.
            if (xlWorkBook != null) { Marshal.ReleaseComObject(xlWorkBook); } //release each workbook like this
            if (xlWorkSheet != null) { Marshal.ReleaseComObject(xlWorkSheet); } //release each worksheet like this
            if (xlApp != null) { Marshal.ReleaseComObject(xlApp); } //release the Excel application
            xlWorkBook = null; //set each memory reference to null.
            xlWorkSheet = null;
            xlApp = null;
            GC.Collect();
    
    0 讨论(0)
提交回复
热议问题