Microsoft로 로그인
로그인하거나 계정을 만듭니다.
안녕하세요.
다른 계정을 선택합니다.
계정이 여러 개 있음
로그인할 계정을 선택합니다.

이 문서가 적용되는 다른 제품을 참조하세요.

증상

.NET Microsoft Office .NET 또는 Microsoft Visual Visual Basic .NET에서 C# 애플리케이션을 자동화하면 종료 메서드를 호출할 Office 애플리케이션이 종료되지 않습니다.

원인

.NET을 Visual Studio 코드에서 COM 개체를 호출하면 RCW(런타임 호출 가능 래퍼)가 자동으로 생성됩니다. RCW 마샬은 .NET 애플리케이션과 COM 개체 간에 호출합니다. RCW는 COM 개체에 대한 참조 수를 유지합니다. 따라서 RCW에서 모든 참조가 릴리스되지 않은 경우 COM 개체가 종료되지 않습니다.

해결 방법

애플리케이션이 Office 있는지 확인하기 위해 자동화 코드가 다음 조건을 충족하는지 여부를 결정합니다.

  • 각 개체를 새 변수로 선언합니다. 예를 들어 다음 코드 줄을 변경합니다.

    oBook = oExcel.Workbooks.Add()
    

    이 변경을 다음으로 변경합니다.

    dim oBooks as Excel.Workbooks
    oBooks = oExcel.Workbooks
    oBook = oBooks.Add()
    
  • System.Runtime.InteropServices.Marshal.ReleaseComObject를 사용하여 개체를 사용한 후 0이 반환될 때까지 루프에서 사용합니다. System.Runtime.InteropServices.Marshal.ReleaseComObject는 RCW의 참조 수를 감소하고, 루프는 CLR을 다시 입력한 횟수에 관계없이 기저 COM 구성 요소가 해제됩니다.

  • 변수에 대한 참조를 해제하기 위해 변수를 Nothing 또는 Null과 같게 설정합니다.

  • 애플리케이션 개체의 종료 Office 사용하여 서버를 종료할지 알 수 있습니다.

상태

이것은 의도적으로 설계된 동작입니다.

추가 정보

동작을 재현하는 단계

  1. .NET Visual Studio 시작합니다.

  2. 파일 메뉴에서 새로 고치기 를 클릭한 다음, Project. 프로젝트 Visual Basic 아래에서 애플리케이션 Windows 선택한 다음 확인을 클릭합니다.

    참고 사항 Form1은 기본적으로 만들어집니다.

  3. 개체 라이브러리에 Microsoft Excel 추가합니다. 이렇게 하려면 다음과 같이 하십시오.

    1. Project 메뉴에서 참조 추가를 클릭합니다.

    2. COM 탭에서 개체 라이브러리를 Excel 선택한 다음 선택을 클릭합니다.

      Microsoft Excel 2002: Microsoft Excel 10.0 개체

      라이브러리Note를 아직 수행하지 않은 경우 PIAS(기본 상호 Microsoft Office)를 다운로드하여 설치하는 것이 좋습니다.

      XP PIAS에 대한 Office 자세한 내용은 다음 Microsoft 기술 자료 문서로 이동하세요.

      328912 Microsoft Office XP 기본 인터프 어셈블리(PIAS)를 다운로드할 수 있습니다.
        2003 Microsoft Office Excel: Microsoft Excel 11.0 개체 라이브러리

    3. 참조 추가 대화 상자에서 확인을 클릭하여 선택을 수락합니다.

  4. 보기 메뉴에서 도구 상자를 클릭한 다음, 단추 컨트롤을 Form1로 드래그합니다.

  5. Button1을 두 번 클릭합니다.

    참고 사항 폼의 코드 창이 나타납니다.

  6. Form1.vb의 맨 위에 다음 코드를 추가합니다.

    Imports Microsoft.Office.Interop
    
  7. 코드 창에서 다음 코드를 바 대체합니다.

        Private Sub Button1_Click(ByVal sender As System.Object, _
           ByVal e As System.EventArgs) Handles Button1.Click
        End Sub
    

    다음 코드를 대체합니다.

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim oApp As New Excel.Application()
        Dim oBook As Excel.Workbook = oApp.Workbooks.Add
        Dim oSheet As Excel.Worksheet = oApp.ActiveSheet
    
        oSheet = Nothing
        oBook.Close(False)
        oBook = Nothing
        oApp.Quit()
        oApp = Nothing
    
        Debug.WriteLine("Sleeping...")
        System.Threading.Thread.Sleep(5000)
        Debug.WriteLine("End Excel")
    End Sub
    
  8. F5를 눌러 애플리케이션을 실행합니다.

  9. 작업 Windows 를 니다. Visual Studio 출력 창을 표시하여 디버그 메시지를 표시합니다. 명령 단추를 클릭합니다. 프로세스 목록에 Excel.exe 인스턴스가 표시됩니다.

  10. 애플리케이션이 Excel 후에도 작업 목록에서 계속 실행됩니다. 대화 상자를 닫고 프로세스 Excel 더 이상 나타나지 않습니다.

  11. "해결" 섹션의 단계를 수행하면 마지막 변수를 Office 애플리케이션이 종료됩니다. 다음 코드를 사용하여 5단계에서 함수를 바 대체합니다.

      Private Sub NAR(ByVal o As Object)
        Try
          While (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0)
          End While
        Catch
        Finally
          o = Nothing
        End Try
      End Sub
    
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim oApp As New Excel.Application()
        Dim oBooks As Excel.Workbooks = oApp.Workbooks
        Dim oBook As Excel.Workbook = oBooks.Add
        Dim oSheet As Excel.Worksheet = oApp.ActiveSheet
    
        NAR(oSheet)
        oBook.Close(False)
        NAR(oBook)
        NAR(oBooks)
        oApp.Quit()
        NAR(oApp)
    
        Debug.WriteLine("Sleeping...")
        System.Threading.Thread.Sleep(5000)
        Debug.WriteLine("End Excel")
    End Sub
    

Visual C# .NET을 사용하는 경우 NAR() 함수에 대한 코드를 참조합니다.

private void NAR(object o)
{
    try 
    {
        while (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0) ;
    }
    catch {}
    finally 
    {
        o = null;
    }
}

참고 .NET Framework 2.0부터 System.Runtime.InteropServices.Marshal.FinalReleaseComObject를 사용하는 동안 루프 호출 System.Runtime.InteropServices.Marshal.ReleaseComObject를 사용하여 동일한 결과를 얻을 수 있습니다.
 

문제 해결

참고 "동작 재현 단계" 섹션에 설명된 단계를 수행하고 서버가 여전히 종료되지 않는 경우 GC를 사용할 수 있습니다. Collect() 메서드 및 GC. 마지막 개체를 릴리스한 후 WaitForPendingFinalizers() 메서드입니다. 런타임이 RCW, GC에서 가비지 수집을 수행하기 때문에 Collect() 메서드는 가비지 수집기 실행을 강제로 실행하고 RCW가 여전히 있는 참조를 해제할 수 있습니다. The GC. Collect() 메서드는 사용 가능한 최대 메모리를 다시 저장합니다. 모든 메모리가 다시 사용된다고 보장하지는 않습니다.

적용 대상

이 문서는 다음에도 적용됩니다.

  • Microsoft Visual Basic .NET(모든 버전)

  • Microsoft Visual C# .NET(모든 버전)

  • Microsoft Office 2016(모든 버전)

  • Microsoft Office 2013(모든 버전)

도움이 더 필요하세요?

더 많은 옵션을 원하세요?

구독 혜택을 살펴보고, 교육 과정을 찾아보고, 디바이스를 보호하는 방법 등을 알아봅니다.

커뮤니티를 통해 질문하고 답변하고, 피드백을 제공하고, 풍부한 지식을 갖춘 전문가의 의견을 들을 수 있습니다.

이 정보가 유용한가요?

언어 품질에 얼마나 만족하시나요?
사용 경험에 어떠한 영향을 주었나요?
제출을 누르면 피드백이 Microsoft 제품과 서비스를 개선하는 데 사용됩니다. IT 관리자는 이 데이터를 수집할 수 있습니다. 개인정보처리방침

의견 주셔서 감사합니다!

×