2012-04-19 12 views
15

Dies ist mein Code, und ich fand viele Antworten für VBA, .NET Framework und ist ziemlich seltsam. Wenn ich dies ausführe, wird Excel geschlossen.Kann Excel nicht vollständig schließen mit win32com auf Python

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

Aber wenn ich folgendes mache, schließt es nicht.

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 !!! 

fand ich einige mögliche Antwort in Stack-Überlauf Frage Excel process remains open after interop; traditional method not working. Das Problem ist, das ist nicht Python, und ich finde Marshal.ReleaseComObject und GC nicht. Ich habe alle Demos auf ...site-packages/win32com und andere angeschaut.

Auch es stört mich nicht, wenn ich nur die PID bekommen und es töten kann.

Ich fand einen Workaround in Kill process based on window name (win32).

Kann nicht der richtige Weg sein, aber ein workround ist:

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 Fügen Sie die Zeile 'excel.DisplayAlerts = False' vor dem Aufruf von' wbs.Open (...) 'hinzu und sehen Sie, ob das hilft. – srgerg

+0

:/nicht funktioniert, ist ein echter Schmerz Excel und COM – sacabuche

+0

Ich finde den Weg, aber keine Verwendung von COM – sacabuche

Antwort

1

ich dies in meinen Dateien, die Excel verwenden:

self.excel.Application.Quit() 
+0

und verwenden Sie DispatchEx oder Dispatch, und es ist wirklich nahe oder läuft weiter? denn in der Tat, wenn ich schließe, scheint es geschlossen zu sein, aber es bleibt am Leben, wenn ich den Task-Manager sehe. – sacabuche

+0

Hoppla, tut mir leid. Ich verwende EnsureDispatch, was den Unterschied ausmachen könnte. Es ist danach total geschlossen. –

6

Try this:

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

del Excel entfernt den Excel-Prozess nicht aus dem Task-Manager – Eildosa

+0

Versuchen Sie, wbs.Close() zu wbs.Close (False) zu ändern, um die Arbeitsmappe zu schließen, ohne zu speichern. –