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.