title: Trapping and handling taskkill in Windows Python
body: <p>I am using Python 2.6.6 for Windows (on Windows XP SP3) with pywin32-218.</p>
  
  <p>In my Python application, I have a second thread (apart from the main thread) which spawns a subprocess to run another Windows executable.</p>
  
  <p>My problem is that when the main process (python.exe) is killed (e.g. using taskkill), I want to terminate the subprocess (calc.exe) and perform some cleaning up.</p>
  
  <p>I tried various methods (atexit, signal and win32api.handleConsoleCtrl), but none seem to be able to trap the taskkill signal.</p>
  
  <p>My code as follows (test.py):</p>
  
  <pre><code>import sys
  import os
  import signal
  import win32api
  import atexit
  import time
  import threading
  import subprocess
  
  class SecondThread(threading.Thread):
      def __init__(self):
          threading.Thread.__init__(self)
          self.secondProcess = None
      def run(self):
          secondCommand = ['C:\WINDOWS\system32\calc.exe']
          self.secondProcess = subprocess.Popen(secondCommand)
          print 'calc.exe running'
          self.secondProcess.wait()
          print 'calc.exe stopped'
          # do cleanup here
      def stop(self):
          if self.secondProcess and self.secondProcess.returncode == None:
              self.secondProcess.kill()
  
  secondThread = SecondThread()
  
  def main():
      secondThread.start()
  
  def cleanup():
      print 'cleaning up'
      secondThread.stop()
      print 'cleaned up'
  
  atexit.register(cleanup)
  
  def handleSignal(signalNum, frame):
      print 'handleSignal'
      cleanup()
      sys.exit(0)
  
  for signalNum in (signal.SIGINT, signal.SIGILL, signal.SIGABRT, signal.SIGFPE, signal.SIGSEGV, signal.SIGTERM):
      signal.signal(signalNum, handleSignal)
  
  def handleConsoleCtrl(signalNum):
      print ('handleConsoleCtrl')
      cleanup()
  
  win32api.SetConsoleCtrlHandler(handleConsoleCtrl, True)
  
  main()
  </code></pre>
  
  <p>The application is launched using</p>
  
  <pre><code>python.exe test.py
  </code></pre>
  
  <p>The console then prints "calc.exe running", and the Calculator application runs, and using Process Explorer, I can see calc.exe as a sub-process of python.exe</p>
  
  <p>Then I kill the main process using</p>
  
  <pre><code>taskkill /pid XXXX /f
  </code></pre>
  
  <p>(where XXXX is the PID for python.exe)</p>
  
  <p>What happens after this is that the command prompt returns without further output (i.e. none of "cleaning up", "handleSignal" or "handleConsoleCtrl" gets printed), the Calculator application continues running, and from Process Explorer, python.exe is no longer running but calc.exe has re-parented itself.</p>