From c1df5bcd9bc9fef1a7e1b3a700ee5994f1c8b2c9 Mon Sep 17 00:00:00 2001 From: Alex Zorin Date: Thu, 27 May 2021 21:40:49 +1000 Subject: [PATCH] windows: fix colors and bold text not rendering --- certbot/CHANGELOG.md | 1 + certbot/certbot/_internal/main.py | 3 +++ certbot/certbot/compat/misc.py | 22 ++++++++++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/certbot/CHANGELOG.md b/certbot/CHANGELOG.md index 76a24c697..b22576b2f 100644 --- a/certbot/CHANGELOG.md +++ b/certbot/CHANGELOG.md @@ -24,6 +24,7 @@ Certbot adheres to [Semantic Versioning](https://semver.org/). * Fix TypeError due to incompatibility with lexicon >= v3.6.0 * Installers (e.g. nginx, Apache) were being restarted unnecessarily after dry-run renewals. +* Colors and bold text should properly render in all supported versions of Windows. More details about these changes can be found on our GitHub repo. diff --git a/certbot/certbot/_internal/main.py b/certbot/certbot/_internal/main.py index 496ce382c..4c6dfac5c 100644 --- a/certbot/certbot/_internal/main.py +++ b/certbot/certbot/_internal/main.py @@ -1519,6 +1519,9 @@ def main(cli_args=None): logger.debug("Arguments: %r", cli_args) logger.debug("Discovered plugins: %r", plugins) + # Some releases of Windows require escape sequences to be enable explicitly + misc.prepare_virtual_console() + # note: arg parser internally handles --help (and exits afterwards) args = cli.prepare_and_parse_args(plugins, cli_args) config = configuration.NamespaceConfig(args) diff --git a/certbot/certbot/compat/misc.py b/certbot/certbot/compat/misc.py index 7c45e49ec..3932981ac 100644 --- a/certbot/certbot/compat/misc.py +++ b/certbot/certbot/compat/misc.py @@ -17,6 +17,8 @@ from certbot.compat import os try: from win32com.shell import shell as shellwin32 + from win32console import GetStdHandle, STD_OUTPUT_HANDLE + from pywintypes import error as pywinerror POSIX_MODE = False except ImportError: # pragma: no cover POSIX_MODE = True @@ -39,6 +41,26 @@ def raise_for_non_administrative_windows_rights() -> None: raise errors.Error('Error, certbot must be run on a shell with administrative rights.') +def prepare_virtual_console() -> None: + """ + On Windows, ensure that Console Virtual Terminal Sequences are enabled. + + """ + if POSIX_MODE: + return + + # https://docs.microsoft.com/en-us/windows/console/setconsolemode + ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004 + + # stdout/stderr will be the same console screen buffer, but this could return None or raise + try: + h = GetStdHandle(STD_OUTPUT_HANDLE) + if h: + h.SetConsoleMode(h.GetConsoleMode() | ENABLE_VIRTUAL_TERMINAL_PROCESSING) + except pywinerror: + logger.debug("Failed to set console mode", exc_info=True) + + def readline_with_timeout(timeout: float, prompt: str) -> str: """ Read user input to return the first line entered, or raise after specified timeout.