Vea los otros productos a los que se aplica este artículo.

Síntomas

Al automatizar una aplicación Microsoft Office de Microsoft Visual Basic .NET o Microsoft Visual C# .NET, la aplicación Office no se cierra al llamar al método Salir.

Causa

Cuando Visual Studio .NET llama a un objeto COM desde código administrado, crea automáticamente un Contenedor de llamadas en tiempo de ejecución (RCW). Los cálculos de cálculo de referencias de RCW llaman entre la aplicación .NET y el objeto COM. El RCW mantiene un recuento de referencias en el objeto COM. Por lo tanto, si no se han publicado todas las referencias en el RCW, el objeto COM no se cierra.

Solución

Para asegurarse de que se Office aplicación, determine si el código de automatización cumple los siguientes criterios:

  • Declare cada objeto como una nueva variable. Por ejemplo, cambie la siguiente línea de código:

    oBook = oExcel.Workbooks.Add()
    

    Cambie esto a lo siguiente:

    dim oBooks as Excel.Workbooks
    oBooks = oExcel.Workbooks
    oBook = oBooks.Add()
    
  • Use System.Runtime.InteropServices.Marshal.ReleaseComObject en un bucle hasta que devuelva 0 cuando haya terminado de usar un objeto. System.Runtime.InteropServices.Marshal.ReleaseComObject decrementa el recuento de referencias del RCW y el bucle se asegura de que el componente COM subyacente se libere independientemente de cuántas veces haya introducido el CLR.

  • Para liberar la referencia a la variable, establezca la variable igual a Nothing o Null.

  • Use el método Salir del objeto Office aplicación para decirle al servidor que se cierre.

Estado

Este comportamiento es una característica del diseño de la aplicación.

Más información

Pasos para reproducir este comportamiento

  1. Inicie Visual Studio .NET.

  2. En el menú Archivo, haga clic en Nuevo y, a continuación, haga clic en Project. En Visual Basic proyectos, seleccione Windows aplicación y, a continuación, haga clic en Aceptar.

    Nota Formulario1 se crea de forma predeterminada.

  3. Agregue una referencia a la Microsoft Excel de objetos. Para ello, siga estos pasos:

    1. En el menú Proyecto, haga clic en Agregar referencia.

    2. En la pestaña COM, busque la biblioteca de objetos para Excel y, a continuación, haga clic en Seleccionar.

      Para Microsoft Excel 2002: Microsoft Excel Biblioteca de objetos 10.0Note

      Si aún no lo ha hecho, le recomendamos que descargue e instale los ensamblados de interoperabilidad primarios (PIA) de Microsoft Office XP.

      Para obtener más información sobre Office PIA de XP, vaya al siguiente artículo de Microsoft Knowledge Base:

      328912 Microsoft Office ensamblados de interoperabilidad primarios (PIA) de XP están disponibles para su descarga
        Para Microsoft Office Excel 2003: Microsoft Excel de objetos 11.0

    3. Haga clic en Aceptar en el cuadro de diálogo Agregar referencias para aceptar las selecciones.

  4. En el menú Ver, haga clic en Cuadro de herramientas y, a continuación, arrastre un control de botón a Form1.

  5. Haga doble clic en Botón1.

    Nota Aparecerá la ventana de código del formulario.

  6. Agregue el código siguiente a la parte superior de Form1.vb:

    Imports Microsoft.Office.Interop
    
  7. Reemplace el siguiente código en la ventana de código:

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

    Sustituya el código siguiente:

    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. Presione la tecla F5 para ejecutar la aplicación.

  9. Abra Windows Administrador de tareas. En Visual Studio, muestre la ventana Salida para ver los mensajes de depuración. Haga clic en el botón de comando. Observe que una instancia de Excel.exe aparece en la lista Procesos.

  10. La instancia de Excel se ejecuta en la lista de tareas incluso después de que la aplicación haya terminado de dormir. Cierre el cuadro de diálogo y observe que Excel ya no aparece en la lista Procesos.

  11. Al realizar los pasos de la sección "Resolución", la aplicación de Office se cierra después de que suelte la última variable. Reemplace la función en el paso 5 con el código siguiente:

      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
    

Si usa Visual C# .NET, haga referencia al código de la función NAR():

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

Nota A partir de .NET Framework 2.0, puede usar System.Runtime.InteropServices.Marshal.FinalReleaseComObject en lugar de las llamadas de bucle while System.Runtime.InteropServices.Marshal.ReleaseComObject para lograr el mismo resultado.
 

Solución de problemas

Nota Si sigue los pasos que se describen en la sección "Pasos para reproducir el comportamiento" y el servidor sigue sin cerrarse, puede usar el GC. Método Collect() y el GC. Método WaitForPendingFinalizers() después de liberar el último objeto. Dado que el tiempo de ejecución realiza la recolección de elementos no utilizados en el RCW, el GC. El método Collect() fuerza al recolector de elementos no utilizados a ejecutarse y puede liberar las referencias que el RCW todavía tiene. El GC. El método Collect() intenta recuperar la memoria máxima disponible. Observe que esto no garantiza que se recuperará toda la memoria.

Se aplica a

Este artículo también se aplica a:

  • Microsoft Visual Basic .NET (todas las ediciones)

  • Microsoft Visual C# .NET (todas las ediciones)

  • Microsoft Office 2016 (todas las ediciones)

  • Microsoft Office 2013 (todas las ediciones)

¿Necesita más ayuda?

Ampliar sus conocimientos

Explorar los cursos >

Obtener nuevas características primero

Unirse a Microsoft Insider >

¿Le ha sido útil esta información?

¿Cuál es tu grado de satisfacción con la calidad del lenguaje?
¿Qué ha afectado a tu experiencia?

¡Gracias por sus comentarios!

×