2012-04-19 14 views
15

Questo è il mio codice e ho trovato molte risposte per VBA, .NET framework ed è piuttosto strano. Quando eseguo questo, Excel si chiude.Impossibile chiudere Excel completamente utilizzando win32com su Python

from win32com.client import DispatchEx 
excel = DispatchEx('Excel.Application') 
wbs = excel.Workbooks 
wbs.Close() 
excel.Quit() 
wbs = None 
excel = None # <-- Excel Closes here 

Ma quando faccio quanto segue, non chiude.

excel = DispatchEx('Excel.Application') 
wbs = excel.Workbooks 
wb = wbs.Open('D:\\Xaguar\\A1.xlsm') 
wb.Close(False) 
wbs.Close() 
excel.Quit() 
wb = None 
wbs = None 
excel = None # <-- NOT Closing !!! 

ho trovato qualche possibile risposta nella domanda Stack Overflow Excel process remains open after interop; traditional method not working. Il problema è che non è Python, e non trovo Marshal.ReleaseComObject e GC. Ho controllato tutte le demo su ...site-packages/win32com e altre.

Anche se non mi dà fastidio se riesco ad ottenere il PID e ad ucciderlo.

Ho trovato una soluzione alternativa in Kill process based on window name (win32).

potrebbe non essere il modo corretto, ma un workround è:

def close_excel_by_force(excel): 
    import win32process 
    import win32gui 
    import win32api 
    import win32con 

    # Get the window's process id's 
    hwnd = excel.Hwnd 
    t, p = win32process.GetWindowThreadProcessId(hwnd) 
    # Ask window nicely to close 
    win32gui.PostMessage(hwnd, win32con.WM_CLOSE, 0, 0) 
    # Allow some time for app to close 
    time.sleep(10) 
    # If the application didn't close, force close 
    try: 
     handle = win32api.OpenProcess(win32con.PROCESS_TERMINATE, 0, p) 
     if handle: 
      win32api.TerminateProcess(handle, 0) 
      win32api.CloseHandle(handle) 
    except: 
     pass 

excel = DispatchEx('Excel.Application') 
wbs = excel.Workbooks 
wb = wbs.Open('D:\\Xaguar\\A1.xlsm') 
wb.Close(False) 
wbs.Close() 
excel.Quit() 
wb = None 
wbs = None 
close_excel_by_force(excel) # <--- YOU #@#$# DIEEEEE!! DIEEEE!!! 
+0

Try aggiungendo la riga 'excel.DisplayAlerts = False' prima della chiamata a' wbs.Open (...) 'e vedere se questo aiuta. – srgerg

+0

:/non funziona, è un vero dolore excel e COM – sacabuche

+0

trovo la strada ma non utilizzando COM – sacabuche

risposta

1

ho questo nel mio file che utilizzano Excel:

self.excel.Application.Quit() 
+0

e stai usando DispatchEx , o Dispatch, e si chiude davvero o continua a funzionare? perché in effetti quando chiudo sembra chiuso ma, si mantiene vivo quando vedo il task manager – sacabuche

+0

Oops mi dispiace. Sto usando ConfirmDispatch che potrebbe fare la differenza. È completamente chiuso in seguito. –

6

Prova questo:

wbs.Close() 
excel.Quit() 
del excel # this line removed it from task manager in my case 
+0

del excel non rimuove il processo di Excel dal task manager – Eildosa

+0

Provare a cambiare wbs.Close() in wbs.Close (False) per chiudere la cartella di lavoro senza salvare. –