0

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?

muralidhar
  • 11
  • 3
  • Simply read in a loop until the pipe is broken when the child process exits – Remy Lebeau Feb 23 '22 at 18:02
  • I suggest you could refer to the thread: https://stackoverflow.com/questions/54416116/readfile-does-not-return-while-reading-stdout-from-a-child-process-after-it-ends – Jeaninez - MSFT Feb 24 '22 at 07:57

0 Answers0