title: Can't close Excel completely using win32com on Python
body: <p>This is my code, and I found many answers for <a href="http://en.wikipedia.org/wiki/Visual_Basic_for_Applications" rel="noreferrer">VBA</a>, .NET framework and is pretty strange. When I execute this, Excel closes.</p>
  
  <pre><code>from win32com.client import DispatchEx
  excel = DispatchEx('Excel.Application')
  wbs = excel.Workbooks
  wbs.Close()
  excel.Quit()
  wbs = None
  excel = None # &lt;-- Excel Closes here
  </code></pre>
  
  <p>But when I do the following, it does not close.</p>
  
  <pre><code>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  # &lt;-- NOT Closing !!!
  </code></pre>
  
  <p>I found some possible answer in Stack Overflow question <em><a href="https://stackoverflow.com/questions/8977571/excel-process-remains-open-after-interop-traditional-method-not-working">Excel process remains open after interop; traditional method not working</a></em>. The problem is that is not Python, and I don't find <code>Marshal.ReleaseComObject</code> and <code>GC</code>. I looked over all the demos on <code>...site-packages/win32com</code> and others.</p>
  
  <p>Even it does not bother me if I can just get the PID and kill it.</p>
  
  <p>I found a workaround in <em><a href="http://python.6.n6.nabble.com/Kill-process-based-on-window-name-win32-td1042063.html" rel="noreferrer">Kill process based on window name (win32)</a></em>.</p>
  
  <p>May be not the proper way, but a workround is:</p>
  
  <pre><code>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) # &lt;--- YOU #@#$# DIEEEEE!! DIEEEE!!!
  </code></pre>