2014-02-26 3 views
4

interop 라이브러리를 사용하여 Excel 파일 시트에서 일부 데이터를 읽습니다. Microsoft.Office.Interop.Excel을 사용하여 데이터를 얻은 다음 시트의 모든 데이터를 읽습니다.Excel 프로세스가 여전히 백그라운드에서 실행됩니다.

Application ExcelApp = new Excel.Application(); 
Workbook excelWorkbook = ExcelApp2.Workbooks.Open(excelFileNamePath); 
_Worksheet excelWorksheet = excelWorkbook.Sheets[excelSheetName]; 
Range excelRange = excelWorksheet.UsedRange; 
//...for loops for reading data 
ExcelApp.Quit(); 

내 응용 프로그램이 종료 된 후에 엑셀 파일을 편집하려고 시도했지만 여는 중에 문제가 발생했습니다. 분명히 엑셀 프로세스는 내가 ExcelApp.Quit()라고 불렀지 만 백그라운드에서 계속 실행됩니다. 응용 프로그램에서 사용하는 Excel 파일을 올바르게 닫는 방법이 있습니까? 나는 C#에 익숙하지 않아서 여기에 뭔가 빠졌을 것이다.

편집 : 해결! 두 개의 점을 사용하지 못하게하는 com 객체의 경우 rule이 분명합니다.

Excel.Application ExcelApp2 = new Excel.Application(); 
Excel.Workbooks excelWorkbooks = ExcelApp2.Workbooks; 
Excel.Workbook excelWorkbook = excelWorkbooks.Open(excelFileName); 
Excel._Worksheet excelWorksheet = excelWorkbook.Sheets[excelSheetName]; 
//... 
excelWorkbook.Close();  
Marshal.ReleaseComObject(excelWorkbook); 
Marshal.ReleaseComObject(excelWorksheet); 
Marshal.ReleaseComObject(excelRange); 
ExcelApp2.Quit(); 
+0

가 살펴 유무 : http://stackoverflow.com/questions/9962157/safely-disposing-excel-interop-objects -in-c – CJBS

+0

해 보셨습니까? http://support.microsoft.microsoft.com/kb/Q317109 –

+0

@CJBS 그들은 답을 찾지 못했습니다! 그러나 나는 거기에있는 제안 중 하나를 구현하려고 노력할 것이다. 감사! – rrh

답변

9

다른 유사한 질문이 있었고 해결책은 이중 점 표기법을 사용하지 않는 것이 었습니다 (https://stackoverflow.com/a/17367570/3063884). 대신, 도중에 사용 된 각 객체에 대한 변수를 정의하고 각각에 대해 Marshal.ReleaseComObject을 개별적으로 사용하십시오.

링크 된 솔루션에서 바로 복사 :

var workbook = excel.Workbooks.Open(/*params*/) 

---> 대신 사용 ->

var workbooks = excel.Workbooks; 
var workbook = workbooks.Open(/*params*/) 

그런 다음, 완료되면, 각 COM 개체 해제 :

Marshal.ReleaseComObject(workbook); 
Marshal.ReleaseComObject(workbooks); 
Marshal.ReleaseComObject(excel); 
+0

방금 ​​같은 질문을 찾았습니다. 감사. – rrh

+0

당신을 진심으로 환영합니다. COM은 지저분해질 수 있습니다. – CJBS

1

통합 문서를 닫지 않을 것입니다. 를 닫은 다음 Excel 응용 프로그램을 종료하기 전에 해제 :

excelWorkbook.close(); 
Marshal.ReleaseComObject(excelWorkbook); 
ExcelApp.Quit(); 
+0

오류가 계속 표시됩니다. 그것은 "이름이있는 문서가 이미 열려 있습니다"라고 말합니다. – rrh

0

상호 운용성은 악명 버그가 ... 난 내 응용 프로그램을 종료 할 때 Excel에서 열린 남아있는 문제가 더 이상 내 통합 문서를 저장하지 않고, 후 다음 방법을 사용 :

while (Marshal.ReleaseComObject(wb) > 0); 
while (Marshal.ReleaseComObject(xl) > 0); 

wb = null; 
xl = null; 

GC.WaitForPendingFinalizers(); 
GC.Collect(); 
GC.WaitForPendingFinalizers(); 
GC.Collect(); 

wb는 내 통합 문서 개체이고 xl은 내 Excel.Application 개체입니다.

+0

그 중 하나는 작동하지 않습니다. 나는 그것이 지금 얼마나 버기인지를 알 수있다, 이것은 매우 고민 거리다! – rrh

+0

위의 코드를 호출하기 전에 물건을 저장하고 닫는 중입니까? 내가 이렇게 : wb.SaveAs ( \t _saveFile, \t Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookDefault, \t Type.Missing, \t Type.Missing, 거짓 \t, \t 거짓, \t Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, \t Type.Missing, \t Type.Missing, \t Type.Missing, \t Type.Missing, \t Type.Missing ); wb.Saved = true; – John

1

오랫동안 대답이 없었지만 나를 위해 일한 것은 GC.Collect();를 호출하는 것이 었습니다. ,

즉 대신 발신자로부터

하지만 아주 작은 변화를 죽지 않는 엑셀 이상 사용

main() 
{ 
    ... 
    doexcelstuff(); 
    ... 
} 

void doexcelstuff() 
{ 
    Excel.Application ExApp2 = new Excel.Application(); 
    Excel.Workbook excelWb = ExApp2 .Workbooks.Open(excelFName); 
    Excel._Worksheet excelWorksheet = excelWb.Sheets[excelSName]; 
    //... 
    excelWb.Close(); 
    ExApp2.Quit();  
    Marshal.ReleaseComObject(excelWb); 
    Marshal.ReleaseComObject(excelWorksheet); 
    Marshal.ReleaseComObject(ExApp2); 
    excelWb = null; 
    excelWorksheet= null; 
    ExApp2= null; 
    GC.Collect(); 
} 

의 GC는

main() 
{ 
    ... 
    doexcelstuff(); 
    GC.Collect();  // <<-- moved the GC to here (the caller) 
    ... 
} 

void doexcelstuff() 
{ 
    Excel.Application ExApp2 = new Excel.Application(); 
    Excel.Workbook excelWb = ExApp2 .Workbooks.Open(excelFName); 
    Excel._Worksheet excelWorksheet = excelWb.Sheets[excelSName]; 
    //... 
    excelWb.Close(); 
    ExApp2.Quit();  
    Marshal.ReleaseComObject(excelWb); 
    Marshal.ReleaseComObject(excelWorksheet); 
    Marshal.ReleaseComObject(ExApp2); 
    excelWb = null; 
    excelWorksheet= null; 
    ExApp2= null; 
    // removed the GC from here 
} 

에서 호출되는 경우에 내 생각 엔 가비지 컬렉터는 힙에서 내부적으로 생성 된 임시 값 (참조/포인터 포함)을 조용히 정리해야합니다. 이 경우에는 COM 개체를 가리키는 것으로 추측됩니다.

는 (그냥 기계가 소스 코드 아래에 어떻게 작동하는지 이해가 전혀 타지 소요됩니다.)

관련 문제