Calling console applications from C++ Builder

I have a set of utilities which are 32 bit console applications which take command line arguments and return output to the console.

How can I incorporate these programs into a C++ Builder program so that I can create a front-end GUI. Note that I don't have the source code for the console apps. (third party software). I need to

a) pass arguments to the apps as command line arguments
b) recover the output of the applications
c) I don't want spurious DOS windows appearing while the apps run.
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.


DWORD StartCommandLine( HWND hDlg )
   HANDLE hInputRead, hInputWrite;
   HANDLE hOutputRead, hOutputWrite;
   HANDLE hDupInputWrite;
   HANDLE hDupOutputRead;
   BOOL bStatus;
   DWORD dwRead, dwAvail, dwMsg, dwRetCode;
   char szInput[ 1024 ];

   memset( &si, 0, sizeof(STARTUPINFO) );             //  Initialize structures
   memset( &pi, 0, sizeof(PROCESS_INFORMATION) );
                                        //  Create pipe for console -> GUI data
   bStatus = CreatePipe( &hInputRead, &hInputWrite, NULL, 1024 );
   if( ! bStatus )
      return( FALSE );
                                        //  Create pipe for GUI -> console data
   bStatus = CreatePipe( &hOutputRead, &hOutputWrite, NULL, 1024 );
   if( ! bStatus )
      CloseHandle( hInputRead );           //  Close first pipe if second fails
      CloseHandle( hInputWrite );
      return( FALSE );
                                   //  Make an inheritable pipe endpoint handle
   DuplicateHandle( GetCurrentProcess(), hInputWrite,
                    GetCurrentProcess(), &hDupInputWrite, 0L, TRUE,
                                            //  and a second for GUI -> console
   DuplicateHandle( GetCurrentProcess(), hOutputRead,
                    GetCurrentProcess(), &hDupOutputRead, 0L, TRUE,

   si.cb = sizeof(STARTUPINFO);
   si.wShowWindow = SW_HIDE;        //  Don't show the console window (DOS box)
   si.hStdOutput = hDupInputWrite;             //  Redirect command line to GUI
   si.hStdError = hDupInputWrite;
   si.hStdInput = hDupOutputRead;  //  and send stuff from here to command line

   hPipeOut = hOutputWrite;                  //  Global so window can access it

   memset( &osvi, 0, sizeof(OSVERSIONINFO) );     //  Initialize version struct
   osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);           //  Fill in size
   GetVersionEx( &osvi );                               //  Get OS version info
                                                            //  Start a DOS box
   if( osvi.dwPlatformId == VER_PLATFORM_WIN32_NT )           //  If it's WinNT
      bStatus = CreateProcess( NULL, "cmd /K", NULL, NULL, TRUE,
                               0, NULL, NULL, &si, &pi );       //  Use CMD.EXE
   else                                           //  Use for Win95
      bStatus = CreateProcess( NULL, "c:\\", NULL, NULL, TRUE,
                               0, NULL, NULL, &si, &pi );

   CloseHandle( hDupInputWrite );               //  Close duplicates so GUI end
   CloseHandle( hDupOutputRead );                         //  can use the pipes

   if( ! bStatus )
      CloseHandle( hInputRead );
      CloseHandle( hInputWrite );
      CloseHandle( hOutputRead );
      CloseHandle( hOutputWrite );
      return( FALSE );
                     //  Loop until either the window closure sets the event or
   while( WaitForSingleObject( hThreadEvent, 0 ) != WAIT_OBJECT_0 )
   {                                                  //  The dos box is closed
      if( WaitForSingleObject( pi.hProcess, 0 ) == WAIT_OBJECT_0 )
         /* get exit code */
         GetExitCodeProcess ( pi.hProcess, &dwRetCode);
         pi.hProcess = NULL;

                                                //  If there's anything to read
      if( PeekNamedPipe( hInputRead, szInput, 1024, &dwRead,
                         &dwAvail, &dwMsg ) )
      {                                               //  Read it into a buffer
         ReadFile( hInputRead, szInput, dwAvail, &dwRead, NULL );
         if( dwRead )                        //  and send to the window control
            SendDlgItemMessage( hDlg, 100, LB_ADDSTRING, 0, (LPARAM)szInput );
      Sleep( 100 );                        //  Sit a spell...kick yer shoes off

   if( pi.hProcess )                     //  If the dos box is running, kill it
      TerminateProcess( pi.hProcess, 0 );

   CloseHandle( hInputWrite );
   CloseHandle( hOutputRead );
   return( TRUE );                                      //  And exit the thread

This example sends the output to a list box, but I'm sure you'll be able to adapt it for your needs...

Feel free to ask if you encounter problems!

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
hpicdAuthor Commented:
That looks pretty good and so quick I hardly had time to get a cup of coffee! I will try it this evening and report back if there are any problems.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.