2013-09-23 1 views
3

Я пытаюсь правильно закрыть COM-объект excel, такой как рабочая тетрадь Excel и рабочий лист. Я просмотрел все решения на этом сайте и на другом сайте. Ничего не работает. Единственный способ - запустить цикл, чтобы убить или преуспеть. есть ли лучший способ или способ убить только один процесс файла excel?Закрытие C# excel COM-объект должным образом

 #region VARIABLE 

      int nColumn = 0; 
      int nIMPORT = 1; 
      int endofsheet = 0; 

      string IMPORTfilepath = null; 
      string nsheet = null; 
      string nCell = null; 
      string lastfilename = "";    

      double rRFDS = 0; 
      double cRFDS = 0; 

      List<String> filename = new List<String>(); 

      object misValue1 = System.Reflection.Missing.Value; 

      //Opening Central DB 
      Excel.Application CentralDB; 
      Excel.Workbook CentralDBWorkBook; 
      Excel.Worksheet CentralDBWorkSheet; 
      Excel.Range CentralDBrange; 

      //Opening RFDS 
      Excel.Application IMPORT; 
      Excel.Workbook IMPORTWorkBook; 
      Excel.Worksheet IMPORTWorkSheet; 

      //Excel.Range RFDSrange; 
      Excel.Range CellAddress; 

     #endregion 

     CentralDB = new Microsoft.Office.Interop.Excel.Application(); 
     CentralDBWorkBook = CentralDB.Workbooks.Open(Odl1.FileName, 0, false, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0); 
     CentralDBWorkSheet = CentralDB.Worksheets.get_Item(1); 

     IMPORT = new Microsoft.Office.Interop.Excel.Application(); 
     IMPORTfilepath = Odl2.FileNames[nIMPORT]; 
     IMPORTWorkBook = IMPORT.Workbooks.Open(IMPORTfilepath, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0); 
     IMPORTWorkSheet = IMPORT.Worksheets.get_Item(1); 

     CentralDBrange = CentralDBWorkSheet.UsedRange;   

     filename = Odl2.FileNames.ToList(); 

     endofsheet = CentralDBrange.Rows.Count;    

     foreach(string fn in filename) 
     { 
      try 
      { 
       IMPORTWorkBook = IMPORT.Workbooks.Open(fn, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0); 
       CentralDBWorkSheet.Cells[nIMPORT + endofsheet, 1] = IMPORTWorkBook.Name; 
       for (nColumn = 3; nColumn <= CentralDBrange.Columns.Count; nColumn++) 
       { 
        nsheet = (string)(CentralDBrange.Cells[2, nColumn].Value2); 
        foreach (Excel.Worksheet ws in IMPORTWorkBook.Sheets) 
        { 
         if (ws.Name.Equals(nsheet)) 
         { 
          IMPORTWorkSheet = IMPORTWorkBook.Worksheets.get_Item(nsheet); 

          nCell = (string)(CentralDBrange.Cells[3, nColumn].Value2); 
          CellAddress = CentralDBWorkSheet.get_Range(nCell, nCell); 

          rRFDS = CellAddress.Row; 
          cRFDS = CellAddress.Column; 
          CentralDBWorkSheet.Cells[nIMPORT + endofsheet, nColumn] = IMPORTWorkSheet.Cells[rRFDS, cRFDS]; 
          label4.Text = nIMPORT.ToString() + "/" + Convert.ToString(Odl2.FileNames.Count()); 
         } 
        } 
       } 
       nIMPORT++; 
       nColumn = 3; 
       CentralDBWorkBook.Save(); 
       IMPORTWorkBook.Close(false, null, null); 
      } 
      catch (System.Exception ex) 
      { 
       MessageBox.Show("Unable to release the Object " + ex.ToString());        
      } 
      lastfilename = fn; 
     } 

     CentralDB.Quit(); 
     releaseObject(CentralDBWorkSheet); 
     releaseObject(CentralDBWorkBook); 
     releaseObject(CentralDB); 

     IMPORT.Quit(); 
     releaseObject(IMPORTWorkSheet); 
     releaseObject(IMPORTWorkBook); 
     releaseObject(IMPORT); 
     GC.Collect(); 
}   

      private void releaseObject(object obj) 
      { 
       try 
       { 
        System.Runtime.InteropServices.Marshal.ReleaseComObject(obj); 
        obj = null; 
       } 
       catch (System.Exception ex) 
       { 
        obj = null; 
        MessageBox.Show("Unable to release the Object " + ex.ToString()); 
       } 
       finally 
       { 
        GC.Collect(); 
       } 

      } 
+0

Возможно, этот предыдущий [вопрос] (http://stackoverflow.com/questions/158706/how-to-correct-clean-up-excel-interop-objects) может вам помочь. – elvin

+0

Совет: используйте как можно меньше ссылок на Excel и старайтесь не хранить их в локальных/временных переменных. Я также посмотрел бы на создание шаблона Singleton для экземпляра Excel. –

ответ

1

Попробуйте этот заказ (плюс .Visible = false):

releaseObject(CentralDBWorkSheet); 
    releaseObject(CentralDBWorkBook); 

    releaseObject(IMPORTWorkSheet); 
    releaseObject(IMPORTWorkBook); 

    CentralDB.Visible = false; 
    IMPORT.Visible = false; 

    CentralDB.Quit(); 
    IMPORT.Quit(); 

    releaseObject(CentralDB); 
    releaseObject(IMPORT); 
+0

Не повезло с этим заказом –

1

В дополнении к моему комментарию ... я использую это и работает так же хорошо ... но опять же, у меня нет ссылки проведенных повсюду.

private void DoReleaseCOMObject(object obj) 
     { 
      int refCounter = Marshal.ReleaseComObject(obj); 
      while (refCounter > 0) 
      { 
       refCounter = Marshal.ReleaseComObject(obj); 
       System.Diagnostics.Debug.WriteLine("ReleaseCOM ref: " + refCounter); 
      } 

      obj = null; 
     } 

private void DoFinalReleaseCOMObject(object obj) 
     { 
      int refCounter = Marshal.FinalReleaseComObject(obj); 
      System.Diagnostics.Debug.WriteLine("FinalReleaseComObject ref: " + refCounter); 

      obj = null; 
     } 

public void Dispose() 
     { 
      System.Diagnostics.Debug.WriteLine("In Dispose"); 
      this.Dispose(false); // because we are doing unmanaged 
      GC.Collect(); 
      GC.SuppressFinalize(this); 
     } 

     protected virtual void Dispose(bool disposing) 
     { 
      System.Diagnostics.Debug.WriteLine("In Dispose (" + disposing + ")"); 
      if (!disposing) // unmanaged 
      { 
       #region COM Cleanup 

       this.DoFinalReleaseCOMObject(this.headerStartCell); 
       this.DoFinalReleaseCOMObject(this.headerEndCell); 
       this.DoFinalReleaseCOMObject(this.headerWriteRange); 

       this.DoFinalReleaseCOMObject(this.startCell); 
       this.DoFinalReleaseCOMObject(this.endCell); 
       this.DoFinalReleaseCOMObject(this.writeRange); 

       this.DoFinalReleaseCOMObject(this.ws); 
       this.DoFinalReleaseCOMObject(this.wb); 
       this.DoFinalReleaseCOMObject(this.wbs); 

       this.DoFinalReleaseCOMObject(this.excelApp); 

       System.Diagnostics.Debug.WriteLine("I've tried to clean"); 

       #endregion 
      } 

      // no need for else condition if dispose is true as we are not dealing with managed objects 
     } 

Да, я реализовал интерфейс IDisposable. У меня также было несколько ссылок на объекты Excel, на которые ссылается/хранится в глобальном масштабе (тот же экземпляр), и это то, что я очищаю onces I quit Excel

 Смежные вопросы

  • Нет связанных вопросов^_^