So I've tried to execute a bat file that install a software for windows. The code works, however it only outputs the once the process is done. Is there a way to synchronize execution and redirecting/reading console output?
I tried to follow this but still get the same output: Is it possible to embed a command prompt in a win32 app?
I've tried to use thread but it still didn't work. The batch was executed and after that the output is then read and printed. Which is not a goal of my project.
Please refer to the code below:
#include <windows.h>
#include <iostream>
#include <string>
#include <thread>
// Function to capture and print the output of a child process
void CaptureChildProcessOutput(HANDLE hChildStdOut) {
char buffer[4096];
DWORD bytesRead;
while (true) {
if (!ReadFile(hChildStdOut, buffer, sizeof(buffer), &bytesRead, nullptr) || bytesRead == 0)
break;
std::string output(buffer, bytesRead);
std::cout << output;
}
}
int main() {
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
HANDLE hChildStdOutRead, hChildStdOutWrite;
if (!CreatePipe(&hChildStdOutRead, &hChildStdOutWrite, &saAttr, 0)) {
std::cerr << "Failed to create pipe." << std::endl;
return 1;
}
STARTUPINFOA si; // Use STARTUPINFOA instead of STARTUPINFO (ANSI version)
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(STARTUPINFOA));
si.cb = sizeof(STARTUPINFOA);
si.hStdError = hChildStdOutWrite;
si.hStdOutput = hChildStdOutWrite;
si.dwFlags |= STARTF_USESTDHANDLES;
// Convert wide string to narrow string
std::wstring cmdLineW = L"cmd.exe /C InstallSoftware.bat"; // Change this to your batch file
std::string cmdLineA(cmdLineW.begin(), cmdLineW.end());
if (!CreateProcessA(NULL, &cmdLineA[0], NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
std::cerr << "CreateProcess failed." << std::endl;
return 1;
}
CloseHandle(hChildStdOutWrite);
// Create a thread to capture and print the child process output
std::thread outputThread(CaptureChildProcessOutput, hChildStdOutRead);
// Wait for the child process to complete
WaitForSingleObject(pi.hProcess, INFINITE);
// Close the thread and process handles
outputThread.join();
CloseHandle(hChildStdOutRead);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
}