Skip to content

Instantly share code, notes, and snippets.

@chikatoike
Created April 20, 2013 02:53
Show Gist options
  • Save chikatoike/5424539 to your computer and use it in GitHub Desktop.
Save chikatoike/5424539 to your computer and use it in GitHub Desktop.
WindowsでGenerateConsoleCtrlEventを使ってctrl-cをエミュレートしてプロセスグループ全体を終了したい。 なぜかforループの2番目は子プロセスと孫プロセスが終了できない。
import sys
import time
import ctypes
import subprocess
CTRL_C_EVENT = 0
CTRL_BREAK_EVENT = 1
if len(sys.argv) == 1:
for i in range(2):
print('start')
proc = subprocess.Popen(['python.exe', sys.argv[0], '2'], shell=True)
# startupinfo = subprocess.STARTUPINFO()
# startupinfo.dwFlags |= subprocess.CREATE_NEW_PROCESS_GROUP
# proc = subprocess.Popen(['python.exe', sys.argv[0], '2'], startupinfo=startupinfo)
print('pid:' + str(proc.pid))
# proc.wait()
time.sleep(2)
ret = ctypes.windll.kernel32.FreeConsole()
print('FreeConsole: ' + str(ret))
ret = ctypes.windll.kernel32.AttachConsole(proc.pid)
print('AttachConsole: ' + str(ret))
ret = ctypes.windll.kernel32.SetConsoleCtrlHandler(0, 1)
print('SetConsoleCtrlHandler: ' + str(ret))
ret = ctypes.windll.kernel32.GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0)
print('GenerateConsoleCtrlEvent: ' + str(ret))
print('Ctrl-Ced')
proc.wait()
time.sleep(1)
time.sleep(3)
elif len(sys.argv) == 2:
proc = subprocess.Popen(['python.exe', sys.argv[0], '2', '3'])
proc.wait()
elif len(sys.argv) == 3:
while True:
time.sleep(3)
print('child living...')
@marineotter
Copy link

8年前なので時効かもしれませんが、

SetConsoleCtrlHandler(0, 1) は実行中のプロセスをCtrl+Cで落ちなくした上で、その後で起動する子プロセスもCtrl+Cで落ちなくします。

なので、一回目のforループで SetConsoleCtrlHandler(0, 1) が呼ばれたあと、二回目に subprocess.Popen でオープンされたプロセスにはCtrl+Cが効かなくなっています。

回避するためには二回目に subpeocess.Popen する前に SetConsoleCtrlHandler(0, 0) で一旦SetConsoleCtrlHandlerを解除すると良いです。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment