I'm programming a library which will make setting colors, modes, etc. easier in console program. But I've encountered a problem with Windows Terminal. For example I have a function:
void WindowsCLI::setUnderlinedFont()
{
auto consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
config.underlined = true;
SetConsoleTextAttribute(consoleHandle, getTextAttribute(config));
}
and it uses COMMON_LVB_UNDERSCORE
attribute from windows.h
to make text underlined. And the result of this function in powershell looks like this:
, and in Windows Terminal like this:, so apparently in the second case my function didn't work properly. I thought that the problem is that the Windows Terminal runs in virtual terminal mode. So I made another function for virtual terminals:
void WindowsVirtualCLI::setUnderlinedFont()
{
printf("\x1b[4m");
}
and now it didn't work for Powershell: , and worked properly for Windows Terminal: . But now I have another problem. How to distinguish that the program is run in Powershell or Windows Terminal. I tried using this function:
CLI& cli()
{
DWORD consoleMode;
auto consoleHandle = GetStdHandle(STD_INPUT_HANDLE);
GetConsoleMode(consoleHandle, &consoleMode);
if ((consoleMode & ENABLE_PROCESSED_OUTPUT) && (consoleMode & ENABLE_VIRTUAL_TERMINAL_PROCESSING))
{
return windows::WindowsVirtualCLI::getInstance();
}
else
{
return windows::WindowsCLI::getInstance();
}
}
But it turned out that both Powershell and Windows Terminal have ENABLE_PROCESSED_OUTPUT
and ENABLE_VIRTUAL_TERMINAL_PROCESSING
enabled. And now, I have no other idea how can I distinguish these terminals in runtime. Do you have any idea how?
P.S.
I have changed cli()
method to this:
CLI& cli()
{
DWORD consoleMode;
auto consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleMode(consoleHandle, &consoleMode);
SetConsoleMode(consoleHandle, consoleMode);
if ((consoleMode & ENABLE_PROCESSED_OUTPUT) && (consoleMode & ENABLE_VIRTUAL_TERMINAL_PROCESSING))
{
return windows::WindowsVirtualCLI::getInstance();
}
else
{
return windows::WindowsCLI::getInstance();
}
}
And still it doesn't work as I need to.
CodePudding user response:
A simple way to detect whether you're running in Windows Terminal is to check if the WT_SESSION
environment variable is defined (has a value).
According to this answer, getenv("WT_SESSION")
should work for retrieving the value of that variable, if defined.
Note:
This isn't foolproof, because if you launch a regular console window (
conhost.exe
) from a shell running in Windows Terminal, it'll likely inherit theWT_SESSION
variable.The more cumbersome alternative is to walk the (chain of) parent processes to look for a process named
WindowsTerminal
.