2012-01-23 19 views
6

Ben hata ayıklama bazı kod ile bir konuya koşuyorum. Excel interop bir çalışma kitabından bazı değerleri ayıklamak için kullanılır; ancak, program çıktıktan sonra Excel açık kalır. Geleneksel çözüm denedim, ama yine de kod ( Excel işlemi birlikte çalıştıktan sonra açık kalır; geleneksel yöntem çalışmıyor

private void TestExcel() 
    { 
     Excel.Application excel = new Excel.Application(); 
     Excel.Workbooks books = excel.Workbooks; 
     Excel.Workbook book = books.Open("C:\\test.xlsm"); 

     book.Close(); 
     books.Close(); 
     excel.Quit(); 

     Marshal.ReleaseComObject(book); 
     Marshal.ReleaseComObject(books); 
     Marshal.ReleaseComObject(excel); 
    } 

bile bu kod basit parça birden fazla dosya ile çalışan işlem tutar çalıştırılan tüm makinelerde açık Excel'e bir başvuru tutan xlsm, xlsx XLS). Şu anda açtığımız Excel süreçlerini öldürmek için bir geçici çözümümüz var, fakat bunu kendi aklımıza uygun hale getirmeyi tercih ediyorum.

Workbook değişkenine daraltılmış olarak eklemeliyim. Aramayı books.Open() ve tüm başvuruları book'a kaldırırsam, başarıyla kapanır.

+0

Kodunuz test ettiğimde çalıştı, soruna neden olarak çalışma zamanında bir istisna olabilir mi? – msmucker0527

cevap

11

Bu benim için başarıyla çalıştı); bu kodla herhangi bariz sorunlara işaret etmek çekinmeyin, gerçekten uzak COM okuryazar olmaktan duyuyorum

// 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(); 
} 
+2

Yanıt olarak işaretlendi, çünkü bu doğru. Dev makinemde hala çalışmıyor olsa da, bu, temiz bir yüklemede veya ev bilgisayarımda çalışır. Garip. – bradenb

3

Toplam COM amatörüyüm, uzun bir süre önce bir projede küçük bir şey için kullandım, ancak işte burada kullanmış olduğum bir kod parçacığı. Muhtemelen çevrimiçi bir yerde buldum, hatırlamıyorum. Her durumda, ben onun tam zafer yapıştırmak;) Şimdi de denemek edemiyorum

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(); 
     } 
    } 
} 

, ama muhtemelen (dürüst) hiçbir ayrıntıyı hatırlamıyorum çalıştı. Belki sana yardım eder.

 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(); 
+1

Bu çalışma kısmen sonunda GC.Collect() öğesinin sonunda sonunda yakalamayı deneyin. Bununla birlikte, nihayet parçaya ulaşıncaya kadar excel'i gerçekten kapatmaz. Niye ya ? çünkü nesneyi değer ile geçirirsiniz, eğer sayfayı/sayfaları/çalışma kitabını geçirirseniz veya işlevsellikte başarılı olursanız. Nesnenin kendisi ile ne yaparsanız yapın, COM değerleri aynı kalacaktır. Bu COM nesnesini referans olarak iletemezseniz, ama denedim ve izin vermezdim. –

2

Bu benim Bu sorunu gidermek var nasıl:

0

Bu kod benim için çalışır.

//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 bu konu ile ilgili bazı faydalı bilgiler var.

İlgili konular