2011-04-01 8 views
10

Tengo el siguiente código:C# = ¿Por qué los procesos de Excel no terminan?

private bool IsMousetrapFile(string path) 
    { 

     logger.Log(validateFileMessage + path); 

     Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application(); 
     Excel.Workbooks workbooks = xlApp.Workbooks; 
     Excel.Workbook xlWorkBook = workbooks.Open(path, Type.Missing, Type.Missing, 
      Type.Missing, Type.Missing, Type.Missing, 
      Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
      Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); 
     Excel.Sheets worksheets = (Excel.Sheets)xlWorkBook.Worksheets; 
     Excel.Worksheet ws = null; 


     foreach (string sheet in expectedWorksheets) 
     { 

      try 
      { 

       ws = (Excel.Worksheet)worksheets.get_Item(sheet); 
       logger.Log(validMousetrapFileMessage + path); 
      } 
      catch 
      { 
       logger.Log(validateSheetError + sheet + ": " + path); 
       if (ws != null) 
        Marshal.ReleaseComObject(ws); 
       Marshal.ReleaseComObject(worksheets); 
       Marshal.ReleaseComObject(xlWorkBook); 
       Marshal.ReleaseComObject(workbooks); 
       Marshal.ReleaseComObject(xlApp); 

       return false; 

      } 

     } 

     if (ws != null) 
      Marshal.ReleaseComObject(ws); 
     Marshal.ReleaseComObject(worksheets); 
     Marshal.ReleaseComObject(xlWorkBook); 
     Marshal.ReleaseComObject(workbooks); 
     Marshal.ReleaseComObject(xlApp); 

     return true; 


    } 

Efectivamente, comprueba si un libro de Excel contiene hojas específicas. Independientemente de si hay o no, quiero que los procesos de Excel finalicen. Sin embargo, cada vez que se abre un nuevo libro de trabajo, se agrega un nuevo proceso y nunca se elimina?

PS. Sé que hay código duplicado allí ... se debe arreglar pronto :)

+2

Aquí está la víctima como si preguntó: http://stackoverflow.com/questions/5357244/quitting-excel-with-c-while-using-excel-automation – gideon

+0

vea el enlace para obtener más detalles sobre cuándo Excel todavía se ejecuta cuando llama a dejar de fumar. – gideon

Respuesta

10

Use Excel.Application.Quit() cuando haya terminado con el procesamiento o lo que sea que esté haciendo.

En su caso: xlApp.Quit();

ACTUALIZACIÓN:

@Lasse V. Karlsen señaló qué hacer si Excel ya estaba corriendo. Bueno, aquí es una solución: (No he probado el código, esto es sólo para darle una idea)

private void TestMethod() 
{ 
    bool excelWasRunning = System.Diagnostics.Process.GetProcessesByName("excel").Length > 0; 

    // your code 

    if (!excelWasRunning) 
    { 
     xlApp.Quit(); 
    } 
} 
+0

Perfecto - gracias. Lo había intentado, pero después de lanzar proyectos similares, y por supuesto arrojó una excepción. Usarlo antes del lanzamiento funciona un encanto. –

+0

@Darren Young: gr8 – HABJAN

+0

Eso es, por supuesto, muy grosero de hacer si el usuario abre Excel y luego inicia la aplicación ... –

1

Pocos días atrás he implementado exportación/importación. Obtuve el código de abajo cuando busqué en Google y funciona bien.

ExportToExcel() 
{ 
    try 
    { 
     //your code 
    } 
    catch (Exception ex) 
     { 

     } 
     finally 
     { 
      TryQuitExcel(Application_object); 
     } 
} 
private static void TryQuitExcel(Microsoft.Office.Interop.Excel.Application application) 
     { 
      try 
      { 
       if (application != null && 
        application.Workbooks != null && 
        application.Workbooks.Count < 2) 
       { 
        application.DisplayAlerts = false; 
        application.Quit(); 
        Kill(application.Hwnd); 
        System.Runtime.InteropServices.Marshal.FinalReleaseComObject(application); 
        application = null; 
       } 
      } 
      catch 
      { 
       /// Excel may have been closed via Windows Task Manager. 
       /// Skip the close. 
      } 
     } 


private static void Kill(int hwnd) 
    { 
     int excelPID = 0; 
     int handle = hwnd; 
     GetWindowThreadProcessId(handle, ref excelPID); 

     Process process = null; 
     try 
     { 
      process = Process.GetProcessById(excelPID); 

      // 
      // If we found a matching Excel proceess with no main window 
      // associated main window, kill it. 
      // 
      if (process != null) 
      { 
       if (process.ProcessName.ToUpper() == "EXCEL" && !process.HasExited) 
        process.Kill(); 
      } 
     } 
     catch { } 
    } 
3

Mi solución

[DllImport("user32.dll")] 
static extern int GetWindowThreadProcessId(int hWnd, out int lpdwProcessId); 

private void GenerateExcel() 
{ 
    var excel = new Microsoft.Office.Interop.Excel.Application(); 
    int id; 
    // Find the Process Id 
    GetWindowThreadProcessId(excel.Hwnd, out id); 
    Process excelProcess = Process.GetProcessById(id); 

try 
      { 
       // Your code 
} 
finally 
{ 
    excel.Quit(); 

    // Kill him ! 
    excelProcess.Kill(); 
} 
Cuestiones relacionadas