2012-04-19 27 views
15

To jest mój kod i znalazłem wiele odpowiedzi dla VBA, platformy .NET i jest dość dziwne. Kiedy to zrobię, Excel się zamknie.Nie można całkowicie zamknąć programu Excel przy użyciu Win32com na Pythonie

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

Ale kiedy robię co następuje, to się nie zamyka.

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

znalazłem kilka możliwych odpowiedzi w przepełnienie stosu pytanie Excel process remains open after interop; traditional method not working. Problem polega na tym, że nie jest to Python i nie znajduję Marshal.ReleaseComObject i GC. Przejrzałem wszystkie dema na ...site-packages/win32com i innych.

Nawet mnie to nie przeszkadza, jeśli mogę po prostu uzyskać PID i zabić go.

Znalazłem obejście w Kill process based on window name (win32).

może nie być właściwym sposobem, ale workround jest:

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 dodanie linii 'excel.DisplayAlerts = False' przed wywołaniem' wbs.Open (...) 'i zobacz, czy to pomaga. – srgerg

+0

:/nie działa, to prawdziwy ból excel i COM – sacabuche

+0

Znajduję sposób, ale nie używając COM – sacabuche

Odpowiedz

1

mam to w moich plików, które używają Excel:

self.excel.Application.Quit() 
+0

i używasz DispatchEx lub Dispatch i naprawdę się zamyka lub działa? ponieważ w rzeczywistości, kiedy zamykam, wydaje się być zamknięta, ale utrzymuje się przy życiu, gdy widzę menedżera zadań. – sacabuche

+0

Oops przepraszam za to. Korzystam z narzędzia MakeDispatch, które może mieć znaczenie. Jest całkowicie zamknięty. –

6

Spróbuj tego:

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

del excel nie usuwa procesu Excel z menedżera zadań – Eildosa

+0

Spróbuj zmienić wbs.Close() na wbs.Close (False), aby zamknąć skoroszyt bez zapisywania. –

Powiązane problemy