Sintomas
Quando automatiza uma aplicação Microsoft Office a partir do Microsoft Visual Basic .NET ou Microsoft Visual C# .NET, a aplicação Office não sai quando liga para o método Sair.
Causa
Quando Visual Studio .NET chama um objeto COM a partir de um código gerido, cria automaticamente um RCW (Runtime Callable Wrapper). O RCW liga entre a aplicação .NET e o objeto COM. O RCW mantém uma contagem de referências no objeto COM. Por conseguinte, se todas as referências não foram lançadas no RCW, o objeto COM não é desabreado.
Resolução
Para se certificar de que a Office aplicação sai, determine se o seu código de automatização cumpre os 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 isto para o seguinte:
dim oBooks as Excel.Workbooks oBooks = oExcel.Workbooks oBook = oBooks.Add()
-
Utilize System.Runtime.InteropServices.ReleaseComObject num ciclo até que devolva 0 quando terminar de utilizar um objeto. O System.Runtime.InteropServices.ReleaseComObject diminui a contagem de referência do RCW e o ciclo garante que o componente COM subjacente é lançado independentemente do número de vezes que voltar a introduzi-lo.
-
Para libertar a referência à variável, defina a variável igual a Nada ou Nulo.
-
Utilize o método Sair do objeto Office aplicação para pedir ao servidor para encerrar.
Estado
Este comportamento é por estrutura.
Mais Informações
Passos para reproduzir o comportamento
-
Inic Visual Studio .NET.
-
No menu Ficheiro, clique em Novo e, em seguida, clique em Project. Em Projetos Visual Basic, selecione Windows Aplicação e, em seguida, clique em OK.
Nota O formulário1 é criado por predefinição. -
Adicione uma referência à Biblioteca Microsoft Excel Objetos da Biblioteca de Objetos. Para o fazer, siga estes passos:
-
No menu Project, clique em Adicionar Referência.
-
No separador COM, localize a Biblioteca de Objetos Excel, em seguida, clique em Selecionar.
Para Microsoft Excel 2002: Microsoft Excel 10.0 Object LibraryNote
Caso ainda não o tenha feito, recomendamos que transfira e instale as Assemblagens de Interação Principais (PIAs) do Microsoft Office XP.
Para obter mais informações sobre Office XP PIAs, vá ao seguinte artigo da Base de Dados de Conhecimento Microsoft:328912 Microsoft Office interojunções principais (PIAs) XP estão disponíveis para transferência
Para Microsoft Office Excel 2003: Biblioteca de objetos Microsoft Excel 11.0 -
Clique em OK na caixa de diálogo Adicionar Referências para aceitar as suas seleções.
-
-
No menu Ver, clique em Caixa de Ferramentas e, em seguida, arraste um Controlo de botão para o Formulário1.
-
Faça duplo clique em Botão1.
Nota A janela de código do formulário é exibida. -
Adicione o seguinte código à parte superior de Formulário1.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
-
Prima F5 para executar a aplicação.
-
Abra o Windows de Tarefas. No Visual Studio, apresentar a janela Saída para ver as mensagens de depuração. Clique no botão de comando. Repare que uma instância Excel.exe aparece na lista Processos.
-
A instância do Excel ainda é executada na lista de tarefas mesmo depois de a aplicação terminar de dormir. Feche a caixa de diálogo e repare Excel que já não aparece na lista Processos.
-
Ao seguir os passos na secção "Resolução", a aplicação Office sairá após libertar a última variável. Substitua a função no Passo 5 através do 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 estiver a utilizar Visual C# .NET, referenciar 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;
}
}
Nota A partir do .NET Framework 2.0, pode utilizar System.Runtime.InteropServices.FinalReleaseComObject em vez do system.Runtime.InteropServices.SolteComObject para obter o mesmo resultado.
Resolução de problemas
Note Se seguir os passos descritos na secção "Passos para Reproduzir o Comportamento" e o servidor continuar a não encerrar, pode utilizar o GC. Método Recolher() e GC. Método WaitForPendingFinalizers() após libertar o último objeto. Uma vez que o runtime efetua coleções de lixo no RCW, o GC. O método Collect() força o recolhidor do lixo a ser executado e pode lançar quaisquer referências que o RCW ainda tenha. O GC. Método Recolher() tenta recuperar a memória máxima disponível. Repare que isto não garante que toda a memória será recuperada.
Aplica-se 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)