I would like to launch one console c++ application from another c++ application with WIN32 API CreateProcess. This child console application returns some result and i want to read the result of child process in my parent application. Here is my code.
void executeCommand(const std::string& lpCommandLine)
{
PROCESS_INFORMATION processInfo;
STARTUPINFOA startupInfo;
SECURITY_ATTRIBUTES saAttr;
HANDLE stdoutReadHandle = NULL;
HANDLE stdoutWriteHandle = NULL;
std::string outbuf;
DWORD bytes_read;
char tBuf[257];
DWORD exitcode;
BOOL bSuccess = FALSE;
memset(&saAttr, 0, sizeof(saAttr));
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
// Create a pipe for the child process's STDOUT.
if (!CreatePipe(&stdoutReadHandle, &stdoutWriteHandle, &saAttr, 5000))
{
return;
}
// Ensure the read handle to the pipe for STDOUT is not inherited.
if (!SetHandleInformation(stdoutReadHandle, HANDLE_FLAG_INHERIT, 0))
{
return;
}
memset(&startupInfo, 0, sizeof(startupInfo));
startupInfo.cb = sizeof(startupInfo);
startupInfo.hStdError = stdoutWriteHandle;
startupInfo.hStdOutput = stdoutWriteHandle;
startupInfo.wShowWindow = SW_HIDE;
startupInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
startupInfo.dwFlags |= STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
if (!CreateProcessA(NULL, (LPSTR)lpCommandLine.c_str(), NULL, NULL, TRUE, CREATE_NEW_CONSOLE,
NULL,
0, &startupInfo,
&processInfo))
{
return;
}
CloseHandle(stdoutWriteHandle);
for (;;)
{
bSuccess = ReadFile(stdoutReadHandle, tBuf, 256, &bytes_read, NULL);
if (!bSuccess || bytes_read == 0)
{
break;
}
if (bytes_read > 0)
{
tBuf[bytes_read] = '\0';
outbuf += tBuf;
}
}
cmdOutput_ = outbuf;
if (WaitForSingleObject(processInfo.hProcess, INFINITE) != WAIT_OBJECT_0)
{
return;
}
if (!GetExitCodeProcess(processInfo.hProcess, &exitcode))
{
return;
}
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
}
Now my question is, is there possibility that ReadFile returns immediately without reading any data, or without reading complete data from child process stdout and still return non-zero value (which is success)?
If so, then what is the best way to make sure that the complete data is read and only then i can continue parent process?