diff --git a/src/fu-tool.c b/src/fu-tool.c index c8af13f0e..8d7584168 100644 --- a/src/fu-tool.c +++ b/src/fu-tool.c @@ -3080,6 +3080,7 @@ main(int argc, char *argv[]) gboolean ignore_vid_pid = FALSE; g_auto(GStrv) plugin_glob = NULL; g_autoptr(FuUtilPrivate) priv = g_new0(FuUtilPrivate, 1); + g_autoptr(GError) error_console = NULL; g_autoptr(GError) error = NULL; g_autoptr(GPtrArray) cmd_array = fu_util_cmd_array_new(); g_autofree gchar *cmd_descriptions = NULL; @@ -3545,11 +3546,12 @@ main(int argc, char *argv[]) fu_util_cmd_array_sort(cmd_array); /* non-TTY consoles cannot answer questions */ - priv->interactive = isatty(fileno(stdout)) != 0; - if (!priv->interactive) { + if (!fu_util_setup_interactive_console(&error_console)) { + g_debug("failed to initialize interactive console: %s", error_console->message); priv->no_reboot_check = TRUE; priv->no_safety_check = TRUE; } else { + priv->interactive = TRUE; /* set our implemented feature set */ fu_engine_request_set_feature_flags( priv->request, diff --git a/src/fu-util-common.c b/src/fu-util-common.c index 8beb2f0d8..3bbcf7395 100644 --- a/src/fu-util-common.c +++ b/src/fu-util-common.c @@ -9,6 +9,7 @@ #include #include #include +#include #ifdef HAVE_GUSB #include #endif @@ -18,6 +19,11 @@ #include #endif +#ifdef _WIN32 +#include +#include +#endif + #include "fu-common.h" #include "fu-device-private.h" #include "fu-device.h" @@ -2487,3 +2493,63 @@ fu_util_is_url(const gchar *perhaps_url) g_str_has_prefix(perhaps_url, "https://"); #endif } + +gboolean +fu_util_setup_interactive_console(GError **error) +{ +#ifdef _WIN32 + HANDLE hOut; + DWORD dwMode = 0; + + /* enable VT sequences */ + hOut = GetStdHandle(STD_OUTPUT_HANDLE); + if (hOut == INVALID_HANDLE_VALUE) { + g_set_error(error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + "failed to get stdout [%u]", + (guint)GetLastError()); + return FALSE; + } + if (!GetConsoleMode(hOut, &dwMode)) { + g_set_error(error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + "failed to get mode [%u]", + (guint)GetLastError()); + return FALSE; + } + dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; + if (!SetConsoleMode(hOut, dwMode)) { + g_set_error(error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + "failed to set mode [%u]", + (guint)GetLastError()); + return FALSE; + } + if (!SetConsoleOutputCP(CP_UTF8)) { + g_set_error(error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + "failed to set output UTF-8 [%u]", + (guint)GetLastError()); + return FALSE; + } + if (!SetConsoleCP(CP_UTF8)) { + g_set_error(error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + "failed to set UTF-8 [%u]", + (guint)GetLastError()); + return FALSE; + } +#else + if (isatty(fileno(stdout)) == 0) { + g_set_error_literal(error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "not a TTY"); + return FALSE; + } +#endif + /* success */ + return TRUE; +} diff --git a/src/fu-util-common.h b/src/fu-util-common.h index f21d01323..7b100d9be 100644 --- a/src/fu-util-common.h +++ b/src/fu-util-common.h @@ -147,3 +147,5 @@ void fu_util_show_unsupported_warn(void); gboolean fu_util_is_url(const gchar *perhaps_url); +gboolean +fu_util_setup_interactive_console(GError **error); diff --git a/src/fu-util.c b/src/fu-util.c index f62f96f0c..030ad4e9b 100644 --- a/src/fu-util.c +++ b/src/fu-util.c @@ -3712,7 +3712,7 @@ main(int argc, char *argv[]) gboolean allow_older = FALSE; gboolean allow_reinstall = FALSE; gboolean enable_ipfs = FALSE; - gboolean is_interactive = TRUE; + gboolean is_interactive = FALSE; gboolean no_history = FALSE; gboolean offline = FALSE; gboolean ret; @@ -3721,6 +3721,7 @@ main(int argc, char *argv[]) g_autoptr(FuUtilPrivate) priv = g_new0(FuUtilPrivate, 1); g_autoptr(GDateTime) dt_now = g_date_time_new_now_utc(); g_autoptr(GError) error = NULL; + g_autoptr(GError) error_console = NULL; g_autoptr(GPtrArray) cmd_array = fu_util_cmd_array_new(); g_autofree gchar *cmd_descriptions = NULL; g_autofree gchar *filter = NULL; @@ -4209,15 +4210,17 @@ main(int argc, char *argv[]) } /* non-TTY consoles cannot answer questions */ - if (isatty(fileno(stdout)) == 0) { - is_interactive = FALSE; + if (!fu_util_setup_interactive_console(&error_console)) { + g_debug("failed to initialize interactive console: %s", error_console->message); priv->no_unreported_check = TRUE; priv->no_metadata_check = TRUE; priv->no_reboot_check = TRUE; priv->no_safety_check = TRUE; priv->no_remote_check = TRUE; - fu_progressbar_set_interactive(priv->progressbar, FALSE); + } else { + is_interactive = TRUE; } + fu_progressbar_set_interactive(priv->progressbar, is_interactive); /* parse filter flags */ if (filter != NULL) {