Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Windows] Improve console IO redirection. #91147

Merged
merged 1 commit into from
Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions platform/windows/console_wrapper_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ int main(int argc, char *argv[]) {
STARTUPINFOW si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);

WCHAR new_command_line[32767];
_snwprintf_s(new_command_line, 32767, _TRUNCATE, L"%ls %ls", exe_name, PathGetArgsW(GetCommandLineW()));
Expand Down
34 changes: 27 additions & 7 deletions platform/windows/os_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,24 @@ void RedirectStream(const char *p_file_name, const char *p_mode, FILE *p_cpp_str
}

void RedirectIOToConsole() {
// Save current handles.
HANDLE h_stdin = GetStdHandle(STD_INPUT_HANDLE);
HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE h_stderr = GetStdHandle(STD_ERROR_HANDLE);

if (AttachConsole(ATTACH_PARENT_PROCESS)) {
// Restore redirection (Note: if not redirected it's NULL handles not INVALID_HANDLE_VALUE).
if (h_stdin != 0) {
SetStdHandle(STD_INPUT_HANDLE, h_stdin);
}
if (h_stdout != 0) {
SetStdHandle(STD_OUTPUT_HANDLE, h_stdout);
}
if (h_stderr != 0) {
SetStdHandle(STD_ERROR_HANDLE, h_stderr);
}

// Update file handles.
RedirectStream("CONIN$", "r", stdin, STD_INPUT_HANDLE);
RedirectStream("CONOUT$", "w", stdout, STD_OUTPUT_HANDLE);
RedirectStream("CONOUT$", "w", stderr, STD_ERROR_HANDLE);
Expand Down Expand Up @@ -173,10 +190,6 @@ void OS_Windows::initialize() {
add_error_handler(&error_handlers);
#endif

#ifndef WINDOWS_SUBSYSTEM_CONSOLE
RedirectIOToConsole();
#endif

FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES);
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_USERDATA);
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_FILESYSTEM);
Expand Down Expand Up @@ -1521,10 +1534,10 @@ void OS_Windows::unset_environment(const String &p_var) const {
}

String OS_Windows::get_stdin_string() {
WCHAR buff[1024];
char buff[1024];
DWORD count = 0;
if (ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), buff, 1024, &count, nullptr)) {
return String::utf16((const char16_t *)buff, count);
if (ReadFile(GetStdHandle(STD_INPUT_HANDLE), buff, 1024, &count, nullptr)) {
return String::utf8((const char *)buff, count);
}

return String();
Expand Down Expand Up @@ -1908,6 +1921,13 @@ String OS_Windows::get_system_ca_certificates() {
OS_Windows::OS_Windows(HINSTANCE _hInstance) {
hInstance = _hInstance;

#ifndef WINDOWS_SUBSYSTEM_CONSOLE
RedirectIOToConsole();
#endif

SetConsoleOutputCP(CP_UTF8);
SetConsoleCP(CP_UTF8);

CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);

#ifdef WASAPI_ENABLED
Expand Down
22 changes: 4 additions & 18 deletions platform/windows/windows_terminal_logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,26 +53,12 @@ void WindowsTerminalLogger::logv(const char *p_format, va_list p_list, bool p_er
}
buf[len] = 0;

int wlen = MultiByteToWideChar(CP_UTF8, 0, buf, len, nullptr, 0);
if (wlen < 0) {
return;
}

wchar_t *wbuf = (wchar_t *)memalloc((len + 1) * sizeof(wchar_t));
ERR_FAIL_NULL_MSG(wbuf, "Out of memory.");
MultiByteToWideChar(CP_UTF8, 0, buf, len, wbuf, wlen);
wbuf[wlen] = 0;

if (p_err) {
fwprintf(stderr, L"%ls", wbuf);
} else {
wprintf(L"%ls", wbuf);
}

memfree(wbuf);
DWORD written = 0;
HANDLE h = p_err ? GetStdHandle(STD_ERROR_HANDLE) : GetStdHandle(STD_OUTPUT_HANDLE);
WriteFile(h, &buf[0], len, &written, nullptr);

#ifdef DEBUG_ENABLED
fflush(stdout);
FlushFileBuffers(h);
#endif
}

Expand Down
Loading