¿Cómo habilitar el modo QuickEdit de la consola de Windows desde Python?

Me gustaría forzar el modo QuickEdit en la consola cuando se ejecuta un script de python y luego deshabilitarlo justo antes de terminar. ¿Hay una manera de hacerlo?

Puede usar ctypes para llamar a GetConsoleMode y SetConsoleMode .

Definiciones de ctypes:

 import msvcrt import atexit import ctypes from ctypes import wintypes kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) # input flags ENABLE_PROCESSED_INPUT = 0x0001 ENABLE_LINE_INPUT = 0x0002 ENABLE_ECHO_INPUT = 0x0004 ENABLE_WINDOW_INPUT = 0x0008 ENABLE_MOUSE_INPUT = 0x0010 ENABLE_INSERT_MODE = 0x0020 ENABLE_QUICK_EDIT_MODE = 0x0040 # output flags ENABLE_PROCESSED_OUTPUT = 0x0001 ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002 ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004 # VT100 (Win 10) def check_zero(result, func, args): if not result: err = ctypes.get_last_error() if err: raise ctypes.WinError(err) return args if not hasattr(wintypes, 'LPDWORD'): # PY2 wintypes.LPDWORD = ctypes.POINTER(wintypes.DWORD) kernel32.GetConsoleMode.errcheck= check_zero kernel32.GetConsoleMode.argtypes = ( wintypes.HANDLE, # _In_ hConsoleHandle wintypes.LPDWORD,) # _Out_ lpMode kernel32.SetConsoleMode.errcheck= check_zero kernel32.SetConsoleMode.argtypes = ( wintypes.HANDLE, # _In_ hConsoleHandle wintypes.DWORD,) # _Out_ lpMode 

Lo siguiente envuelve las funciones WinAPI subyacentes como get_console_mode y set_console_mode . He limitado los envoltorios a operar solo en el búfer de entrada activo de la consola o en el búfer de salida activo, es decir, \\.\CONIN$ y \\.\CONOUT$ . Creo que esto es más sencillo que tener que preocuparse por los descriptores de archivos y los manejadores. Cabe destacar que sys.stdin y sys.stdout pueden redirigirse a otros lugares, como también puede ser el caso de las secuencias de FILE E / S estándar, los descriptores de archivo y los controladores estándar de Windows que puede obtener de GetStdHandle . En estos casos, aún puede abrir CONIN$ y CONOUT$ , siempre que el proceso esté conectado a una consola.

 def get_console_mode(output=False): '''Get the mode of the active console input or output buffer. Note that if the process isn't attached to a console, this function raises an EBADF IOError. ''' device = r'\\.\CONOUT$' if output else r'\\.\CONIN$' with open(device, 'r+') as con: mode = wintypes.DWORD() hCon = msvcrt.get_osfhandle(con.fileno()) kernel32.GetConsoleMode(hCon, ctypes.byref(mode)) return mode.value def set_console_mode(mode, output=False): '''Set the mode of the active console input or output buffer. Note that if the process isn't attached to a console, this function raises an EBADF IOError. ''' device = r'\\.\CONOUT$' if output else r'\\.\CONIN$' with open(device, 'r+') as con: hCon = msvcrt.get_osfhandle(con.fileno()) kernel32.SetConsoleMode(hCon, mode) 

update_console_mode combina las últimas funciones para permitirle pasar los flags que desea establecer y la mask de indicadores para modificar. Esto incluye banderas para borrar. También permite restaurar el modo anterior registrando una función atexit .

 def update_console_mode(flags, mask, output=False, restre=False): '''Update a masked subset of the current mode of the active console input or output buffer. Note that if the process isn't attached to a console, this function raises an EBADF IOError. ''' current_mode = get_console_mode(output) if current_mode & mask != flags & mask: mode = current_mode & ~mask | flags & mask set_console_mode(mode, output) else: restre = False if restre: atexit.register(set_console_mode, current_mode, output) 

Ejemplo:

 if __name__ == '__main__': import os import sys import time if sys.stderr is None: os.close(2) sys.stderr = open('stderr.txt', 'w', buffering=1) print("%#06x, %#06x" % (get_console_mode(), get_console_mode(output=True))) flags = mask = ENABLE_QUICK_EDIT_MODE update_console_mode(flags, mask, restre=True) print("%#06x, %#06x" % (get_console_mode(), get_console_mode(output=True))) time.sleep(10) # check console properties