2015-01-13 16 views
8

Il seguente codice lascia un Microsoft Excel processo in background in esecuzione, fino a dopo il mio programma è uscito:Perché Microsoft.Office.Interop.Excel.Application.Quit() lascia in esecuzione il processo in background?

var excelApplication = new Application(); 
var workbooks = excelApplication.Workbooks; 
var workbook = excelApplication.Workbooks.Open(file.FullName); 

workbook.Close(); 
excelApplication.Workbooks.Close(); 
excelApplication.Quit(); 

Marshal.ReleaseComObject(workbook); 
Marshal.ReleaseComObject(workbooks); 
Marshal.ReleaseComObject(excelApplication); 

Perché? Cosa mi manca?

+0

Hai provato con tutto ciò che è stato rimosso da // // stuff? La ragione principale di ciò sono alcuni riferimenti rimanenti, oggetti allocati e così via. – DrKoch

+0

Vedi http://stackoverflow.com/questions/9962157/safely-disposing-excel-interop-objects-in-c –

+0

Nella mia prova non c'era nulla, ma il commento. Il codice che ho postato era il codice completo/esatto. – skinnysoftware

risposta

16

Got it!

application.Workbooks! = Application.Workbooks

Questa proprietà non espone una variabile, genera un valore. Quindi ogni volta che accedo alla proprietà Workbooks creo un nuovo oggetto COM.

ho corretto il codice e tutto va bene. Grazie a tutti.

var excelApplication = new Application(); 
var workbooks = excelApplication.Workbooks; 
var workbook = workbooks.Open(pathToExcelWorkbook); // Fixed 

workbook.Close(); 
workbooks.Close(); 
excelApplication.Quit(); 

Marshal.ReleaseComObject(workbook); 
Marshal.ReleaseComObject(workbooks); 
Marshal.ReleaseComObject(excelApplication); 
+0

Potresti per favore segnare la vera risposta? –

+2

Ciao @eugene - La tua risposta mi ha sicuramente portato nella giusta direzione, ma non ho trovato che fosse abbastanza specifico per risolvere l'intero problema. Se si confronta la riga 3 nei miei due esempi di codice, si vedrà che il problema è stato il mio errore nel comprendere che la proprietà Workbooks restituirà sempre un nuovo oggetto. – skinnysoftware

5

questo è un problema ampiamente diffuso con le applicazioni di Office. Tutti gli add-in di Excel/le applicazioni di automazione dovrebbero rilasciare sistematicamente i loro riferimenti agli oggetti Excel quando non sono più necessari. Il mancato rilascio sistematico del riferimento agli oggetti Excel può impedire la chiusura corretta di Microsoft Office Excel. Vedere Systematically Releasing Objects per ulteriori informazioni. È correlato a Outlook, ma gli stessi principi possono essere applicati a tutte le applicazioni di Office.

Usa System.Runtime.InteropServices.Marshal.ReleaseComObject per rilasciare un oggetto di Excel quando si è finito di usarlo. Quindi imposta una variabile su Nothing in Visual Basic (null in C#) per rilasciare il riferimento all'oggetto.

+2

Sembra una risposta ragionevole, non è sicuro del motivo per cui è stato downvoted – Kehlan

+0

Questo è ancora il caso nelle versioni di Office più recenti? Il link che hai postato collega alle informazioni del 2007. E se cambio la versione della documentazione (menu a discesa "Altre versioni") non ci sono informazioni su System.Runtime.InteropServices.Marshal.ReleaseComObject per il 2010 o il 2013. –

+1

Lo stesso può essere applicato alle versioni di Office più recenti. –

0

questo è il modo sbagliato di fare COME QUESTO, ma questo è più facile modo per risolvere il problema:

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

    private Application _excelApp; 
    private Workbook _excelWorkBook; 
    private Worksheet _excelSheet; 

    private void CloseExcelApp() 
    { 
     int hWnd = _excelApp.Application.Hwnd; 
     uint processID; 

     GetWindowThreadProcessId((IntPtr)hWnd, out processID); 
     Process.GetProcessById((int)processID).Kill(); 

     _excelWorkBook = null; 
     _excelApp = null; 
     _excelSheet = null; 
    } 

tutto ciò che serve è quello di init tutte le variabili non inizializzate quando è necessario per lavorare con esso e chiamare CloseExcelApp() quando è necessario chiudere l'app.

Problemi correlati