Created
June 23, 2026 14:32
-
-
Save ynkdir/5551f00666741aadef7c63a28ad3c65b to your computer and use it in GitHub Desktop.
Cancel input() with CancelIoEx()
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Cancel input() with CancelIoEx(). | |
| # | |
| # There is known problem: https://github.com/microsoft/terminal/issues/12143 | |
| import msvcrt | |
| import sys | |
| import threading | |
| from win32more import UInt32 | |
| from win32more.Windows.Win32.Foundation import TRUE | |
| from win32more.Windows.Win32.System.Console import INPUT_RECORD, KEY_EVENT, WriteConsoleInput | |
| from win32more.Windows.Win32.System.IO import CancelIoEx | |
| from win32more.Windows.Win32.UI.Input.KeyboardAndMouse import VK_RETURN | |
| exiting = threading.Event() | |
| console_input = msvcrt.get_osfhandle(sys.stdin.fileno()) | |
| def worker(): | |
| while not exiting.wait(3): | |
| cancel_console_input_blocking() | |
| def cancel_console_input_blocking(): | |
| # Cancel input() in main thread. | |
| CancelIoEx(console_input, None) | |
| # WORKAROUND: Reset console internal state by sending key event. | |
| # You need to press Enter twice for second input() without this. | |
| rec = INPUT_RECORD() | |
| rec.EventType = KEY_EVENT | |
| rec.Event.KeyEvent.bKeyDown = TRUE | |
| rec.Event.KeyEvent.wRepeatCount = 1 | |
| rec.Event.KeyEvent.wVirtualKeyCode = VK_RETURN | |
| rec.Event.KeyEvent.uChar.UnicodeChar = "\r" | |
| rec.Event.KeyEvent.dwControlKeyState = 0 | |
| WriteConsoleInput(console_input, rec, 1, UInt32(0)) | |
| def main(): | |
| t = threading.Thread(target=worker) | |
| t.start() | |
| while True: | |
| try: | |
| result = input("Press Enter to exit (canceled in 3 seconds)") | |
| print(f"{result=}") | |
| break | |
| except EOFError: | |
| print("Canceled!") | |
| except KeyboardInterrupt: | |
| print("Interrupted!") | |
| break | |
| exiting.set() | |
| t.join() | |
| if __name__ == "__main__": | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment