2015-01-13 2 views
8

다음 코드는 내 프로그램이 종료 된 후까지, 마이크로 소프트 엑셀 백그라운드 프로세스 실행을 잎 :Microsoft.Office.Interop.Excel.Application.Quit()에서 백그라운드 프로세스가 실행되는 이유는 무엇입니까?

var excelApplication = new Application(); 
var workbooks = excelApplication.Workbooks; 
var workbook = excelApplication.Workbooks.Open(file.FullName); 

workbook.Close(); 
excelApplication.Workbooks.Close(); 
excelApplication.Quit(); 

Marshal.ReleaseComObject(workbook); 
Marshal.ReleaseComObject(workbooks); 
Marshal.ReleaseComObject(excelApplication); 

이유는 무엇입니까? 내가 뭘 놓치고 있니?

+0

'// 물건을 다 드리겠습니다'의 모든 것을 제거 했습니까? 이것의 주된 이유는 나머지 참조, 할당 된 객체 등입니다. – DrKoch

+0

참조 http://stackoverflow.com/questions/9962157/safely-disposing-excel-interop-objects-in-c –

+0

내 테스트에는 거기에 아무것도 있지만 코멘트가 없습니다. 게시 한 코드는 전체/정확한 코드입니다. – skinnysoftware

답변

16

알 수 있습니다.

application.Workbooks! = application.Workbooks

이 속성은 변수를 노출시키지 않고, 그것의 값을 생성한다. 따라서 Workbooks 속성에 액세스 할 때마다 새 COM 개체가 만들어집니다.

코드가 수정되어 모두 정상입니다. 감사합니다 여러분.

var excelApplication = new Application(); 
var workbooks = excelApplication.Workbooks; 
var workbook = workbooks.Open(pathToExcelWorkbook); // Fixed 

workbook.Close(); 
workbooks.Close(); 
excelApplication.Quit(); 

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

진짜 대답을 표시해 주시겠습니까? –

+2

안녕하세요 @ eugene - 귀하의 답변은 확실히 올바른 방향으로 나를 이끌었지만, 전체 문제를 해결할만큼 구체적인 것은 아닙니다. 두 개의 코드 샘플에서 3 행을 비교하면 Workbook 속성이 항상 새로운 개체를 반환한다는 것을 이해하지 못하는 것이 문제라는 것을 알 수 있습니다. – skinnysoftware

5

이것은 Office 응용 프로그램에서 널리 퍼진 문제입니다. 모든 Excel 추가 기능/자동화 응용 프로그램은 더 이상 필요없는 Excel 개체에 대한 참조를 체계적으로 릴리스해야합니다. 체계적으로 Excel 개체에 대한 참조를 해제하지 못하면 Microsoft Office Excel이 제대로 종료되지 않을 수 있습니다. 자세한 내용은 Systematically Releasing Objects을 참조하십시오. Outlook과 관련이 있지만 동일한 원칙을 모든 Office 응용 프로그램에 적용 할 수 있습니다.

Excel 개체를 사용한 후이를 해제하려면 System.Runtime.InteropServices.Marshal.ReleaseComObject를 사용하십시오. 다음 변수를 Visual Basic의 Nothing (C#의 null)으로 설정하여 개체에 대한 참조를 해제합니다.

+2

왜 당신이 downvoted 이유는 확실하지 않은 합리적인 응답처럼 보입니다 – Kehlan

+0

이것은 여전히 ​​최신 Office 버전의 경우입니까? 게시 한 링크는 2007 년 정보에 대한 링크입니다. 그리고 문서의 버전 ("다른 버전"드롭 다운)을 변경하면 2010 또는 2013에 대한 System.Runtime.InteropServices.Marshal.ReleaseComObject에 대한 정보가 없습니다. –

+1

새 Office 버전에도 동일하게 적용 할 수 있습니다. –

0

이것은이 LIKE 할 수있는 잘못된 방법입니다,하지만이 문제 해결하기 위해 가장 쉬운 방법입니다 :

[DllImport("user32.dll")] 
    private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); 

    private Application _excelApp; 
    private Workbook _excelWorkBook; 
    private Worksheet _excelSheet; 

    private void CloseExcelApp() 
    { 
     int hWnd = _excelApp.Application.Hwnd; 
     uint processID; 

     GetWindowThreadProcessId((IntPtr)hWnd, out processID); 
     Process.GetProcessById((int)processID).Kill(); 

     _excelWorkBook = null; 
     _excelApp = null; 
     _excelSheet = null; 
    } 

당신이 필요로하는 모든 당신이 필요로 할 때 모든 초기화되지 않은 변수를 초기화하기 위해서입니다 응용 프로그램을 닫아야 할 때 CloseExcelApp()를 호출하십시오.