I'm building a new Excel workbook in c# by combining the first sheet of a series of different Excel workbooks; subsequently I export the new Workbook to PDF. I made this work, but there is always one Excel instance running by the end of the method.
I had the same issue discussed here with a simpler setup and less Excel objects that I could solve with the GC.Collect command. Now, none of this is working.
public void CombineWorkBooks()
    {
        Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
        xlApp.DisplayAlerts = false;
        xlApp.Visible = false;
        Workbooks newBooks = null;
        Workbook newBook = null;
        Sheets newBookWorksheets = null;
        Worksheet defaultWorksheet = null;
        // Create a new workbook, comes with an empty default worksheet");
        newBooks = xlApp.Workbooks;
        newBook = newBooks.Add(XlWBATemplate.xlWBATWorksheet);
        newBookWorksheets = newBook.Worksheets;
        // get the reference for the empty default worksheet
        if (newBookWorksheets.Count > 0)
        {
            defaultWorksheet = newBookWorksheets[1] as Worksheet;
        }
        // loop through every line in Gridview and get the path' to each Workbook
        foreach (GridViewRow row in CertificadosPresion.Rows)
        {
            string path = row.Cells[0].Text;
            string CertName = CertificadosPresion.DataKeys[row.RowIndex].Value.ToString();
            Workbook childBook = null;
            Sheets childSheets = null;
            // Excel of each line in Gridview
            childBook = newBooks.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);
            childSheets = childBook.Worksheets;
            if (childSheets != null)
            {
                // Build a new Worksheet
                Worksheet sheetToCopy = null;
                // Only first Worksheet of the Workbook belonging to that line
                sheetToCopy = childSheets[1] as Worksheet;
                if (sheetToCopy != null)
                {
                    // Assign the Certificate Name to the new Worksheet 
                    sheetToCopy.Name = CertName;
                    // set PageSetup for the new Worksheet to be copied
                    sheetToCopy.PageSetup.Zoom = false;
                    sheetToCopy.PageSetup.FitToPagesWide = 1;
                    sheetToCopy.PageSetup.FitToPagesTall = 1;
                    sheetToCopy.PageSetup.PaperSize = Microsoft.Office.Interop.Excel.XlPaperSize.xlPaperA4;
                    // Copy that new Worksheet to the defaultWorksheet
                    sheetToCopy.Copy(defaultWorksheet, Type.Missing);
                }
                System.Runtime.InteropServices.Marshal.ReleaseComObject(sheetToCopy);
                childBook.Close(false, Type.Missing, Type.Missing);
                
            }
            System.Runtime.InteropServices.Marshal.ReleaseComObject(childSheets);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(childBook);
        }
        //Delete the empty default worksheet
        if (defaultWorksheet != null) defaultWorksheet.Delete();
        //Export to PDF
        newBook.ExportAsFixedFormat(Microsoft.Office.Interop.Excel.XlFixedFormatType.xlTypePDF, @"C:\pdf\" + SALESID.Text + "_CertPres.pdf", 0, false, true);
        newBook.Close();
        newBooks.Close();
        xlApp.DisplayAlerts = true;
        DownloadFile(SALESID.Text);
        System.Runtime.InteropServices.Marshal.ReleaseComObject(defaultWorksheet);
        System.Runtime.InteropServices.Marshal.ReleaseComObject(newBookWorksheets);
        System.Runtime.InteropServices.Marshal.ReleaseComObject(newBook);
        System.Runtime.InteropServices.Marshal.ReleaseComObject(newBooks);
        xlApp.Quit();
        System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }
        protected void DownloadFile(string Salesid)
    {
        string path = @"c:\\pdf\" + Salesid + "_CertPres.pdf";
        byte[] bts = System.IO.File.ReadAllBytes(path);
        Response.Clear();
        Response.ClearHeaders();
        Response.AddHeader("Content-Type", "Application/octet-stream");
        Response.AddHeader("Content-Length", bts.Length.ToString());
        Response.AddHeader("Content-Disposition", "attachment; filename=" + Salesid + "_CertPres.pdf");
        Response.BinaryWrite(bts);
        Response.Flush();
        Response.End();
    }
The problem must have been related to the call of the DownloadFile Method. I eliminated that call, and the Excel process was properly closed. Some of these operations must have kept a reference to one of the COM objects open, so that they could not be closed. By calling "DownloadFile" at the very end after the GarbageCollect the problem is solved. (I'm not quite sure why)
 
     
     
     
    