Aplicativo do Office não fecha após a automação do cliente Visual Studio .net

IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine translation ou MT), não tendo sido portanto revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática… erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.

Clique aqui para ver a versão em Inglês deste artigo: 317109
Este artigo foi arquivado. Este artigo é oferecido "tal como está" e deixará de ser actualizado.
Sintomas
Quando você automatizar um aplicativo Microsoft Office Microsoft Visual Basic .net ou Visual de Microsoft C# .net, o aplicativo do Office não fecha quando chamar o método Quit .
Causa
Quando chamadas Visual Studio .net uma COM objeto de gerenciados código, ele cria automaticamente um Runtime Callable Wrapper (RCW). O RCW empacota chamadas entre o aplicativo .net e o objeto COM. O RCW mantém um Contagem de referência no objeto COM. Portanto, se todas as referências não foram lançado no RCW, o objeto COM não sair.
Resolução
Para certificar-se de que fecha o aplicativo do Office, certifique-se Se o seu código de automação atende aos seguintes critérios:
  • Declare cada objeto como uma nova variável. Por exemplo, alterar a seguinte linha de código
    oBook = oExcel.Workbooks.Add()					
    para o seguinte:
    dim oBooks as Excel.WorkbooksoBooks = oExcel.WorkbooksoBook = oBooks.Add()					
  • Use System.Runtime.InteropServices.Marshal.ReleaseComObject em um loop até que ela retorna 0 quando terminar de usar um objeto. O System.Runtime.InteropServices.Marshal.ReleaseComObject diminui a contagem de referência do RCW e o loop irá garantir que o componente COM subjacente é lançado independentemente de como muitas vezes tem reinseridos no CLR.
  • Para liberar a referência à variável, definir a variável igual a Nada ou Nulo.
  • Use o Sair método do objeto de aplicativo do Office para informar o servidor desligar.
Ponto Da Situação
Isso comportamento é por design.
Mais Informação

Etapas para reproduzir o comportamento

  1. Inicie Visual Studio .net.
  2. No menu arquivo , clique em novo e clique em projeto. Em Projetos de Visual Basic, selecione Windows Application e clique em OK. Form1 é criado por padrão.
  3. Adicione uma referência à Biblioteca de objetos do Microsoft Excel. Para fazer isso, execute estas etapas:
    1. No menu Project , clique em Adicionar referência.
    2. Na guia COM , localize a biblioteca de objeto do Excel e clique em Selecionar.

      Para o Microsoft Excel 2002: Microsoft Excel 10.0 Object Library

      Observação Se você não tiver feito isso, é recomendável que você Baixe e instale o Microsoft Office XP Primary Interop Assemblies (PIAs). Para obter informações adicionais sobre PIAs do Office XP, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
      328912Assemblies de interoperabilidade primários (PIAs) de Microsoft Office XP estão disponíveis para download
      Para Microsoft Office do Excel 2003: Microsoft Excel 11.0 Object Library
    3. Clique em OK na caixa de diálogo Add References para aceitar as seleções.
  4. No menu Exibir , clique em Ferramentase, em seguida, arraste um controle Button para Form1.
  5. Clique duas vezes em Button1. Aparece a janela de código para o formulário.
  6. Adicione o seguinte código na parte superior do Form1:
    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					
    com o seguinte:
    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 o Gerenciador de tarefas do Windows. Visual Studio, exibir o Janela de saída para ver as mensagens de depuração. Clique no botão de comando e observe que uma instância do Excel. exe aparece na lista de processos .
  10. A instância do Excel ainda é executado na lista de tarefas ainda Após o aplicativo dormindo. Feche a caixa de diálogo e observe que Excel não aparece mais na lista de processos .
  11. Ao implementar as etapas na seção "Resolução", Encerra o aplicativo do Office depois de liberar a última variável. Substituir o função na etapa 5 com 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 SubPrivate 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 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: Começando com o.NET Framework 2.0, você pode usar System.Runtime.InteropServices.Marshal.FinalReleaseComObject em vez de while loop chamada System.Runtime.InteropServices.Marshal.ReleaseComObject para obter o mesmo resultado.

Solução de problemas

Observe que se você seguir as etapas descritas na A seção "Passos para reproduzir o comportamento" e o servidor ainda não desligar para baixo, você pode usar o GC.Collect () método e o GC .WaitForPendingFinalizers() método depois de liberar o último objeto. Porque o tempo de execução realiza a coleta de lixo em RCW, o GC .Collect () método força o coletor de lixo para executar e pode liberar qualquer referências que ainda tem o RCW. GC .Collect () método tenta recuperar a memória máxima disponível. Observe que Isso não garante que toda a memória será recuperada.
GC.Collect ReleaseComObject; FinalReleaseComObject

Aviso: Este artigo foi traduzido automaticamente

Propriedades

ID do Artigo: 317109 - Última Revisão: 12/07/2015 08:49:04 - Revisão: 1.0

Microsoft Visual Basic .NET 2003 Standard Edition, Microsoft Visual C# .NET 2003 Standard Edition, Microsoft Visual Basic .NET 2002 Standard Edition, Microsoft Visual C# .NET 2002 Standard Edition

  • kbnosurvey kbarchive kbautomation kbprb kbmt KB317109 KbMtpt
Comentários
ERROR: at System.Diagnostics.Process.Kill() at Microsoft.Support.SEOInfrastructureService.PhantomJS.PhantomJSRunner.WaitForExit(Process process, Int32 waitTime, StringBuilder dataBuilder, Boolean isTotalProcessTimeout)