Ответ 1
Как сказал Эриксон, это можно решить, установив режим виртуального терминала. Если вам нужен только цвет PowerShell, вы можете добавить переключатель /A
к вашему вызову в CMD.exe, иначе вам понадобится небольшой процесс, который обрабатывает такой тип, как прокладка, но тот, который также гарантирует VTM включен. Это не совсем плохо, поскольку этот уровень абстракции может пригодиться для будущих случаев использования и ошибок.
Единственной "странной" частью этого фрагмента будет мое использование rel-path. Этот фрагмент - это прокладка процесса из подкаталога для запуска пакетной прокладки из одного каталога.
Важными частями кода являются заголовки для включения и включения VTM для StdOut после получения дескриптора консоли.
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <Windows.h>
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#endif
bool uses_whitespace(std::string test_string)
{
size_t path_white_space_query = test_string.find(' ', 0);
if (path_white_space_query != std::string::npos)
{
return true;
}
return false;
}
int main(int argc, char* argv[])
{
std::string this_app_path = std::string(argv[0]);
auto it = this_app_path.find_last_of("\\", std::string::npos);
std::string path(this_app_path, 0, it);
// Just forwarding the args that were sent to this shim to a batch in a known location,
// making sure whitespace arguments keep their quotes when forwarded.
// CMD.exe will need proper quote-handling, or the call will get mangled.
std::string str = "C:\\Windows\\System32\\cmd.exe /C \"\"" + path + "\\..\\app_shim.bat\"";
std::vector<std::string> args;
std::copy(argv + 1, argv + argc, std::back_inserter(args));
for (auto const& arg : args)
{
if (uses_whitespace(arg))
{
str += (" \"" + arg + "\"");
}
else
{
str += (" " + arg);
}
}
// end-of-CMD-call final wrapping quote
str += "\"";
HANDLE stdOutHandle = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD mode = 0;
GetConsoleMode(stdOutHandle, &mode);
SetConsoleMode(stdOutHandle, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
int exit_code = system(str.c_str());
CloseHandle(stdOutHandle);
return exit_code;
}