diff --git a/main/forwarder/source/main.cpp b/main/forwarder/source/main.cpp index d28739aac..a7d218563 100644 --- a/main/forwarder/source/main.cpp +++ b/main/forwarder/source/main.cpp @@ -64,29 +64,71 @@ int launchExecutable() { auto executablePath = wolv::io::fs::getExecutablePath(); auto executableFullPath = executablePath->parent_path() / "imhex-gui.exe"; - ::PROCESS_INFORMATION process = { }; - ::STARTUPINFOW startupInfo = { .cb = sizeof(::STARTUPINFOW) }; + // Handles for the pipes + HANDLE hChildStdoutRead, hChildStdoutWrite; - // Create a new process for imhex-gui.exe with the same command line as the current process - if (::CreateProcessW(executableFullPath.wstring().c_str(), ::GetCommandLineW(), nullptr, nullptr, FALSE, 0, nullptr, nullptr, &startupInfo, &process) == FALSE) { - // Handle error if the process could not be created + // Security attributes to allow the pipes to be inherited + SECURITY_ATTRIBUTES saAttr; + saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); + saAttr.lpSecurityDescriptor = nullptr; + saAttr.bInheritHandle = TRUE; - // Get formatted error message from the OS - auto errorCode = ::GetLastError(); - auto errorMessageString = std::system_category().message(int(errorCode)); - - // Generate error message - auto errorMessage = fmt::format("Failed to start ImHex:\n\nError code: 0x{:08X}\n\n{}", errorCode, errorMessageString); - - // Display a message box with the error - ::MessageBoxA(nullptr, errorMessage.c_str(), "ImHex Forwarder", MB_OK | MB_ICONERROR); - - return EXIT_FAILURE; + // Create pipes for stdout redirection + if (!::CreatePipe(&hChildStdoutRead, &hChildStdoutWrite, &saAttr, 0)) { + return 1; } - // Wait for the main ImHex process to exit - ::WaitForSingleObject(process.hProcess, INFINITE); - ::CloseHandle(process.hProcess); + // Set up the STARTUPINFO structure for the child process + STARTUPINFO si; + ::ZeroMemory(&si, sizeof(STARTUPINFO)); + si.cb = sizeof(STARTUPINFO); + si.hStdOutput = hChildStdoutWrite; // Redirect stdout to the parent process + si.dwFlags |= STARTF_USESTDHANDLES; // Enable redirection of stdin, stdout, stderr + + PROCESS_INFORMATION pi; + ::ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); + + // Create the child process + if (!::CreateProcessW( + executableFullPath.c_str(), + ::GetCommandLineW(), // Command line + nullptr, // Process security attributes + nullptr, // Thread security attributes + TRUE, // Inherit handles + 0, // Creation flags + nullptr, // Environment + nullptr, // Current directory + &si, // STARTUPINFO + &pi // PROCESS_INFORMATION + )) { + return 1; + } + + // Close unnecessary pipe handles in the parent process + ::CloseHandle(hChildStdoutWrite); + + // Read the child process's stdout and stderr and redirect them to the parent's stdout + DWORD bytesRead; + std::array buffer; + + while (true) { + // Read from stdout + if (::ReadFile(hChildStdoutRead, buffer.data(), buffer.size(), &bytesRead, nullptr)) { + // Write to the parent's stdout + if (bytesRead > 0) + ::WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buffer.data(), bytesRead, &bytesRead, nullptr); + } else { + break; + } + } + + // Wait for the child process to exit + ::WaitForSingleObject(pi.hProcess, INFINITE); + + // Clean up + ::CloseHandle(pi.hProcess); + ::CloseHandle(pi.hThread); + ::CloseHandle(hChildStdoutRead); return EXIT_SUCCESS; } diff --git a/main/gui/source/window/win_window.cpp b/main/gui/source/window/win_window.cpp index ed4fbb024..22d7c2c8c 100644 --- a/main/gui/source/window/win_window.cpp +++ b/main/gui/source/window/win_window.cpp @@ -402,13 +402,6 @@ namespace hex { } else if (hex::getEnvironmentVariable("__IMHEX_FORWARD_CONSOLE__") == "1") { // Check for the __IMHEX_FORWARD_CONSOLE__ environment variable that was set by the forwarder application - // If it's present, attach to its console window - ::AttachConsole(ATTACH_PARENT_PROCESS); - - // Reopen stdin, stdout and stderr to the console if not in debug mode - reopenConsoleHandle(STD_INPUT_HANDLE, STDIN_FILENO, stdin); - reopenConsoleHandle(STD_OUTPUT_HANDLE, STDOUT_FILENO, stdout); - // Enable ANSI colors in the console log::impl::enableColorPrinting(); } else {