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
-
Inicie Visual Studio .NET.
-
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. -
Adicione uma referência à biblioteca de Microsoft Excel de objetos. Para fazer isso, siga estas etapas:
-
No menu Project, clique em Add Reference.
-
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
-
Clique em OK na caixa de diálogo Adicionar Referências para aceitar suas seleções.
-
-
No menu Exibir, clique em Caixa de Ferramentas e arraste um controle Button para Form1.
-
Clique duas vezes em Botão1.
Observação A janela de código do formulário é exibida. -
Adicione o seguinte código à parte superior de Form1.vb:
Imports Microsoft.Office.Interop
-
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
-
Pressione F5 para executar o aplicativo.
-
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.
-
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.
-
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)