Saltar al contenido

Matar el proceso EXCEL.exe de C# en un servicio de Windows

Después de de nuestra extensa selección de información resolvimos este asunto que pueden tener algunos los lectores. Te regalamos la respuesta y nuestro deseo es servirte de gran apoyo.

Solución:

Cerrar correctamente el libro de Excel abierto y salir de la aplicación es extremadamente difícil. Si puedo encontrar los enlaces, los publicaré, pero esencialmente debes limpia todas las referencias a cualquier objeto COM que crees. Esto incluye todo, desde conexiones ODBC (conexiones de datos), hojas de trabajo, libros de trabajo y la aplicación Excel. Una combinación en la que me puse a trabajar involucró la recolección de basura y la System.Runtime.InteropServices.Marshal objeto:

// Garbage collecting
GC.Collect();
GC.WaitForPendingFinalizers();
// Clean up references to all COM objects
// As per above, you're just using a Workbook and Excel Application instance, so release them:
workbook.Close(false, Missing.Value, Missing.Value);
xlApp.Quit();
Marshal.FinalReleaseComObject(workbook);
Marshal.FinalReleaseComObject(xlApp);

Como mencionó, recorrer y eliminar cada proceso de Excel generalmente no es una buena idea, ya que si está ejecutando esto como una aplicación de Windows, puede cerrar Excel en su usuario, o en un servicio también cerrar una instancia de Excel que se está ejecutando a través de algún otro programa.

Editar: consulte esta pregunta para obtener más información.

Debe verificar los identificadores de archivos y obtener PID, que se abren por proceso y luego eliminarlo. Funcionó para mí.

private void genExcel(

   int pid = -1;
   //Get PID
   xlApp = new Excel.Application();
   HandleRef hwnd = new HandleRef(xlApp, (IntPtr)xlApp.Hwnd);
   GetWindowThreadProcessId(hwnd, out pid);
   .
   .
   .
   .
   //Finally
   KillProcess(pid,"EXCEL");


[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int GetWindowThreadProcessId(HandleRef handle, out int processId);

private void KillProcess(int pid, string processName)

    // to kill current process of excel
    System.Diagnostics.Process[] AllProcesses = System.Diagnostics.Process.GetProcessesByName(processName);
    foreach (System.Diagnostics.Process process in AllProcesses)
    
       if (process.Id == pid)
       
         process.Kill();
       
    
    AllProcesses = null;

¡Después de mucha lectura y frustración, encontré una solución!

Todo el crédito es para dotNetkow, nightcoder y Mike Rosenblum por sus soluciones en esta publicación: ¿Cómo limpio correctamente los objetos de interoperabilidad de Excel?

Aquí esta lo que hice…

1. Se cambió el modo de compilación del proyecto a “Lanzamiento” (en el modo DEBUG, los objetos COM tienen dificultades para deshacerse de sus referencias.


2. Se eliminaron todas las expresiones de doble punto (todos los objetos COM deben vincularse a una variable para que puedan liberarse)

3. Llamar a GC.Collect(), GC.WaitForPendingFinalizers() y Marshal.FinalReleaseComObject() explícitamente en un bloque finalmente.

Aquí está el código acutal que estoy usando:

Application xlApp = null;
Workbooks workbooks = null;
Workbook workbook = null;
Worksheet sheet = null;
Range r = null;
object obj = null;

try

    xlApp = new Application();
    xlApp.DisplayAlerts = false;
    xlApp.AskToUpdateLinks = false;
    workbooks = xlApp.Workbooks;
    workbook = workbooks.Open(fileName, 2, false);
    sheet = workbook.Worksheets[1];

    r = sheet.get_Range("F19");
    obj = r.get_Value(XlRangeValueDataType.xlRangeValueDefault);

finally

    GC.Collect();
    GC.WaitForPendingFinalizers();
    if (value != null) Marshal.FinalReleaseComObject(value);
    if (r != null) Marshal.FinalReleaseComObject(r);
    if (sheet != null) Marshal.FinalReleaseComObject(sheet);
    if (workbooks != null) Marshal.FinalReleaseComObject(workbooks);
    if (workbook != null)
    
        workbook.Close(Type.Missing, Type.Missing, Type.Missing);
        Marshal.FinalReleaseComObject(workbook);
    
    if (xlApp != null)
    
        xlApp.Quit();
        Marshal.FinalReleaseComObject(xlApp);
    

valoraciones y comentarios

Si estás de acuerdo, tienes la opción de dejar una división acerca de qué te ha parecido este tutorial.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *