windows: fix colors and bold text not rendering (#8872)

Fixes #8848.
This commit is contained in:
alexzorin 2021-05-29 03:36:51 +10:00 committed by GitHub
parent 18631b99ef
commit 3380694fa8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 26 additions and 0 deletions

View file

@ -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.

View file

@ -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)

View file

@ -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.