Aplica-se a
Visual Studio 2015

Consulte os outros produtos aos que este artigo se aplica.

Sintomas

Quando você automatiza um aplicativo Microsoft Office do Microsoft Visual Basic .NET ou do Microsoft Visual C# .NET, o aplicativo Office não sai quando você chama o método Quit.

Causa

Quando Visual Studio .NET chama um objeto COM do código gerenciado, ele cria automaticamente um Wrapper Callable (RCW) do Tempo de Execução. O RCW empacota chamadas entre o aplicativo .NET e o objeto COM. O RCW mantém uma contagem de referência no objeto COM. Portanto, se todas as referências não foram lançadas no RCW, o objeto COM não será parado.

Resolução

Para garantir que o aplicativo Office seja Office, determine se o código de automação atende aos seguintes critérios:

  • Declare cada objeto como uma nova variável. Por exemplo, altere a seguinte linha de código:

    oBook = oExcel.Workbooks.Add()
    

    Altere isso para o seguinte:

    dim oBooks as Excel.Workbooks
    oBooks = oExcel.Workbooks
    oBook = oBooks.Add()
    
  • Use System.Runtime.InteropServices.Marshal.ReleaseComObject em um loop até que ele retorne 0 quando terminar de usar um objeto. O System.Runtime.InteropServices.Marshal.ReleaseComObject decrementa a contagem de referência do RCW e o loop garante que o componente COM subjacente seja lançado independentemente de quantas vezes ele tenha entrado na CLR.

  • Para liberar a referência à variável, de definir a variável igual a Nothing ou Null.

  • Use o método Quit do objeto Office aplicativo para dizer ao servidor para desligar.

Status

Este é o comportamento padrão.

Informações adicionais

Etapas para reproduzir o comportamento

  1. Inicie Visual Studio .NET.

  2. No menu Arquivo, clique em Novo e clique em Project. Em Visual Basic Projetos, selecione Windows Aplicativo e clique em OK.Observação Form1 é criado por padrão.

  3. Adicione uma referência à biblioteca de Microsoft Excel de objetos. Para fazer isso, siga estas etapas:

    1. No menu Project, clique em Add Reference.

    2. Na guia COM, localize a Biblioteca de Objetos para Excel e clique em Selecionar.Para Microsoft Excel 2002: Microsoft Excel 10.0 Object LibraryNote Se você ainda não tiver feito isso, recomendamos baixar e instalar os PIAs (Conjuntos de Interop Primários) do Microsoft Office XP.Para obter mais informações sobre Office XP PIAs, acesse o seguinte artigo da Base de Dados de Conhecimento da Microsoft:

      328912 Microsoft Office conjuntos de interop primários de XP (PIAs) estão disponíveis para download   Para Microsoft Office Excel 2003: Microsoft Excel biblioteca de objetos 11.0

    3. Clique em OK na caixa de diálogo Adicionar Referências para aceitar suas seleções.

  4. No menu Exibir, clique em Caixa de Ferramentas e arraste um controle Button para Form1.

  5. Clique duas vezes em Botão1.Observação A janela de código do formulário é exibida.

  6. Adicione o seguinte código à parte superior de Form1.vb:

    Imports Microsoft.Office.Interop
    
  7. Substitua o seguinte código na janela de código:

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

    Substitua o seguinte código:

    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. Pressione F5 para executar o aplicativo.

  9. Abra Windows Gerente de Tarefas. Em Visual Studio, exibe a janela Saída para ver as mensagens de depuração. Clique no botão de comando. Observe que uma instância de Excel.exe aparece na lista Processos.

  10. A instância do Excel ainda é executado na lista de tarefas mesmo depois que o aplicativo terminar de dormir. Feche a caixa de diálogo e observe que Excel aparece mais na lista Processos.

  11. Quando você faz as etapas na seção "Resolução", o aplicativo Office é liberado depois que ele libera a última variável. Substitua a função na Etapa 5 usando o seguinte código:

      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
    

Se você estiver usando o Visual C# .NET, consulte o código da função NAR():

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

Observação A partir do .NET Framework 2.0, você pode usar System.Runtime.InteropServices.Marshal.FinalReleaseComObject em vez de chamar System.Runtime.InteropServices.Marshal.ReleaseComObject para obter o mesmo resultado.  

Solução de problemas

Observação Se você seguir as etapas descritas na seção "Etapas para reproduzir o comportamento" e o servidor ainda não for desligado, você poderá usar o GC. Método Collect() e o GC. Método WaitForPendingFinalizers() depois de liberar o último objeto. Como o tempo de execução executa a coleta de lixo no RCW, o GC. O método Collect() força o coletor de lixo a ser executado e pode liberar quaisquer referências que o RCW ainda tenha. O GC. O método Collect() tenta recuperar a memória máxima disponível. Observe que isso não garante que toda a memória será recuperada.

Aplicável a

Este artigo também se aplica a:

  • Microsoft Visual Basic .NET (todas as edições)

  • Microsoft Visual C# .NET (todas as edições)

  • Microsoft Office 2016 (todas as edições)

  • Microsoft Office 2013 (todas as edições)

Precisa de mais ajuda?

Quer mais opções

Explore os benefícios da assinatura, procure cursos de treinamento, saiba como proteger seu dispositivo e muito mais.