title: Execute DOS program and get output dynamically
body: <p>I need to execute a 'DOS' program (console app) and to retrieve its output dynamically (it will be also nice to be able to end the DOS program whenever I want because the DOS program may run for hours). </p>
  
  <p>I have this this function, but it sometimes (rarely) freezes. 
  I need a new function or to fix the one below. </p>
  
  <pre><code>procedure ExecuteAndGetOutDyn(CONST ACommand, AParameters: String; AMemo: TMemo);
  CONST
    CReadBuffer = 128*KB;  //original was 2400bytes
  VAR
    SecurityAttrib: TSecurityAttributes;
    hRead: THandle;
    hWrite: THandle;
    StartupInfo: TStartupInfo;
    ProcessInfo: TProcessInformation;
    pBuffer: array[0..CReadBuffer] of AnsiChar;
    dRead: DWord;
    dRunning: DWord;
    WasOK: Boolean;
  begin
    SecurityAttrib.nLength := SizeOf(TSecurityAttributes);
    SecurityAttrib.bInheritHandle := True;
    SecurityAttrib.lpSecurityDescriptor := nil;
  
    if CreatePipe(hRead, hWrite, @SecurityAttrib, 0) then
     begin
      FillChar(StartupInfo, SizeOf(TStartupInfo), #0);
      StartupInfo.cb         := SizeOf(TStartupInfo);
      StartupInfo.hStdInput  := hRead;
      StartupInfo.hStdOutput := hWrite;
      StartupInfo.hStdError  := hWrite;
      StartupInfo.dwFlags    := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
      StartupInfo.wShowWindow:= SW_HIDE;
  
      if CreateProcess(NIL, PChar(ACommand + ' ' + AParameters), @SecurityAttrib, @SecurityAttrib, True, NORMAL_PRIORITY_CLASS, NIL, NIL, StartupInfo, ProcessInfo) then
       begin
        REPEAT
          dRunning:= WaitForSingleObject(ProcessInfo.hProcess, 100);
          Application.ProcessMessages;
          REPEAT
            dRead := 0;
            WasOK := Windows.ReadFile(hRead, pBuffer[0], CReadBuffer, dRead, NIL);
            if NOT WasOK then mesajerror('Cannot read console output.');
            pBuffer[dRead] := #0;
  
            OemToAnsi(pBuffer, (pBuffer));
            AMemo.Lines.Add(String(pBuffer));
          UNTIL (dRead &lt; CReadBuffer) OR NOT WasOK;
        UNTIL (dRunning &lt;&gt; WAIT_TIMEOUT) { OR Abort};
        CloseHandle(ProcessInfo.hProcess);
        CloseHandle(ProcessInfo.hThread);
       end;
  
      CloseHandle(hRead);
      CloseHandle(hWrite);
     end;
  end;
  </code></pre>
  
  <hr>
  
  <p>The big problem is that there are no certain conditions under which the procedure freezes. I just call the ExecuteAndGetOutDyn and SOMETIMES it freezes after the 'DOS' program finishes. I will post the conditions in which the freeze appears as soon as I discover them.</p>