issue a warning in legacy W10 terminals (PS/cmd)

Those terminal emulators block stdout/stderr output when scrolled,
which effectively stops UltraGrid. The behavior doesn't occur in MS
Terminal app, which is encouraged instead.

Note that Windows Terminal still runs cmd.exe or powershell.exe as a shell
while the cmd/PS process can acts like both terminal emulator and
shell. We also do not trigger the warning if UG is run from within
MSYS2 terminal.
This commit is contained in:
Martin Pulec
2024-01-26 15:04:53 +01:00
parent 7393a244f8
commit bb2a72f67f
3 changed files with 61 additions and 8 deletions

View File

@@ -116,6 +116,8 @@ extern "C" {
#include <mcheck.h> #include <mcheck.h>
#endif #endif
#define MOD_NAME "[host] "
using std::array; using std::array;
using std::cout; using std::cout;
using std::endl; using std::endl;
@@ -458,6 +460,16 @@ struct init_data *common_preinit(int argc, char *argv[])
if (init_com) { if (init_com) {
com_initialize(&init.com_initialized, nullptr); com_initialize(&init.com_initialized, nullptr);
} }
// warn in W10 "legacy" terminal emulators
if ((win_has_ancestor_process("powershell.exe") ||
win_has_ancestor_process("cmd.exe")) &&
!win_has_ancestor_process("WindowsTerminal.exe")) {
MSG(WARNING, "Running inside PS/cmd terminal is not recommended "
"because scrolling the output freezes the process, "
"consider using Windows Terminal instead!\n");
Sleep(1000);
}
#endif #endif
if (strstr(argv[0], "run_tests") == nullptr) { if (strstr(argv[0], "run_tests") == nullptr) {

View File

@@ -35,21 +35,18 @@
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config_unix.h"
#include "config_win32.h"
#endif
#include "utils/windows.h"
#ifdef _WIN32 #ifdef _WIN32
#include <audioclient.h> #include <audioclient.h>
#include <objbase.h> #include <objbase.h>
#include <tlhelp32.h>
#include <vfwmsgs.h> #include <vfwmsgs.h>
#include "debug.h" #include "debug.h"
#endif // defined _WIN32 #endif // defined _WIN32
#include "utils/windows.h"
#define MOD_NAME "[utils/win] "
bool com_initialize(bool *com_initialized, const char *err_prefix) bool com_initialize(bool *com_initialized, const char *err_prefix)
{ {
#ifdef _WIN32 #ifdef _WIN32
@@ -183,6 +180,49 @@ const char *win_wstr_to_str(const wchar_t *wstr) {
} }
return res; return res;
} }
static bool
GetProcessInfo(HANDLE hSnapshot, DWORD processId, PROCESSENTRY32 *pe32)
{
if (!Process32First(hSnapshot, pe32)) {
return false;
}
do {
if (pe32->th32ProcessID == processId) {
return true;
}
} while (Process32Next(hSnapshot, pe32));
return false;
}
/**
* @returns true if there is a process "name" among current process ancestors
* @param name the searched process name (case insensitive)
*/
bool
win_has_ancestor_process(const char *name)
{
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) {
return false;
}
DWORD pid = GetCurrentProcessId();
PROCESSENTRY32 pe32 = { .dwSize = sizeof(PROCESSENTRY32) };
while (GetProcessInfo(hSnapshot, pid, &pe32)) {
MSG(DEBUG, "%s: %s PID: %ld, PPID: %ld\n", __func__
pe32.szExeFile, pid, pe32.th32ParentProcessID);
if (_stricmp(pe32.szExeFile, name) == 0) {
CloseHandle(hSnapshot);
return true;
}
pid = pe32.th32ParentProcessID;
}
CloseHandle(hSnapshot);
return false;
}
#endif // defined _WIN32 #endif // defined _WIN32
/* vim: set expandtab sw=8 tw=120: */ /* vim: set expandtab sw=8 tw=120: */

View File

@@ -85,6 +85,7 @@ void com_uninitialize(bool *com_initialized);
const char *hresult_to_str(HRESULT res); const char *hresult_to_str(HRESULT res);
const char *get_win32_error(DWORD error); const char *get_win32_error(DWORD error);
const char *win_wstr_to_str(const wchar_t *wstr); const char *win_wstr_to_str(const wchar_t *wstr);
bool win_has_ancestor_process(const char *name);
#endif // defined _WIN32 #endif // defined _WIN32
#ifdef __cplusplus #ifdef __cplusplus