How to run a Console app from Graphic app and pick up the output 
Author Message
 How to run a Console app from Graphic app and pick up the output

Hello,

I'm trying to execute a console program from a graphic (MFC)
application (under Win 95, with VC5), without showing its console, and
pick up its standard output (or error) in a CString
variable. I think ShellExecute (or ShellExecuteEx)
doesn't allow to get program's stdout. So I tryed to
do it with CreateProcess redirecting standard handles.

If someone has a similar experiance or knows how to do
the thing properly, please help. I would really apreciate
any help.

Here is my code which doesn't work all the time. I'm not
sure about some parameters (I marked this lines of the
code with ****).

BOOL MyExecCommandWithOutput(CString& strList, LPTSTR lpCommandLine ,
LPVOID lpEnv)
/*
   strList: receives the stdout or stderr
   lpCommandLine: pointer to the command line
   lpEnv: pointer to the new environment
*/
{

        DWORD dwExitCode;
        HANDLE hChildStdoutRd , hChildStdoutWr;
        HANDLE hChildStderrRd , hChildStderrWr;

        SECURITY_ATTRIBUTES saAttr;
        PROCESS_INFORMATION piProcInfo;
        STARTUPINFO siStartInfo;

        // Set up members of SECURITY_ATTRIBUTES structure.
        ZeroMemory( &saAttr, sizeof(SECURITY_ATTRIBUTES) );
        saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);

        // **** I'm not sure about this
        saAttr.bInheritHandle = TRUE;

        if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, PIPEBUF))
                MyErrorExit("Stdout pipe creation failed\n");

        if (! CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, PIPEBUF))
                MyErrorExit("Stdout pipe creation failed\n");

        // Set up members of STARTUPINFO structure.
        ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
        siStartInfo.cb = sizeof(STARTUPINFO);
        siStartInfo.lpReserved = NULL;
        siStartInfo.lpReserved2 = NULL;
        siStartInfo.cbReserved2 = 0;
        siStartInfo.lpDesktop = NULL;

        // Use created pipes as stdout and stderr
        siStartInfo.dwFlags = STARTF_USESTDHANDLES;
        siStartInfo.hStdOutput = hChildStdoutWr;  
        siStartInfo.hStdError = hChildStderrWr;

        // Don't show program's console
        // **** I'm not sure about this
        DWORD dwFlag =  DETACHED_PROCESS;

        // Create the child process.
        BOOL bl;
        bl = CreateProcess(NULL,
                lpCommandLine, // command line
                NULL,          // process security attributes
                NULL,          // primary thread security attributes
                TRUE,          // handles are inherited **** I'm not sure about this
                dwFlag,        // creation flags
                lpEnv,         // environment
                NULL,          // use parent's current directory
                &siStartInfo,  // STARTUPINFO pointer
                &piProcInfo);  // receives PROCESS_INFORMATION

        if (!bl)
        MyErrorExit("Create process failed");

        if (!GetExitCodeProcess(piProcInfo.hProcess, &dwExitCode))
                MyErrorExit("GetExitCodeProcess failed.\n");

        // Close the write end of the pipe before reading from the
    // read end of the pipe.
    if (! CloseHandle(hChildStdoutWr) ||
                ! CloseHandle(hChildStderrWr) )
        MyErrorExit("Closing handle failed");

        // Get the results
        if (dwExitCode != 1) {
                // Program exited with code 0.
                // Read the stdout.
                MyReadFile2Str(strList , hChildStdoutRd);
                if (! CloseHandle(hChildStdoutRd) ||
                        ! CloseHandle(hChildStderrRd) )
                        MyErrorExit("Closing handle failed");
                return TRUE;
        }
        else {
                // Program exited with nonzero code.
                // Read the stderr.
                MyReadFile2Str(strList , hChildStderrRd);
                if (! CloseHandle(hChildStdoutRd) ||
                        ! CloseHandle(hChildStderrRd) )
                        MyErrorExit("Closing handle failed");
                return FALSE;
        }

Quote:
}

VOID MyReadFile2Str(CString& str , HANDLE hRead)
/*
   str: receives the results
   hRead: handle to the file to read from
*/
{
        str.Empty();
    DWORD dwRead;
        CHAR chBuf[BUFSIZE+1];

    // Read output from hRead handle, and write it in the chBuf array.
        BOOL br;
    for (;;) {
                br = ReadFile(hRead, chBuf, BUFSIZE, &dwRead, NULL);
                if (!br || dwRead == 0)
                        break;

                strlist += CString(chBuf, dwRead);
        }
        return;

Quote:
}

___________________________________________________________
Vartan Akopian
University of Southern California
Department of Mathematics
1042 W. 36th Place, DRB 155
Los Angeles, CA 90089-1113



Wed, 04 Jul 2001 03:00:00 GMT  
 How to run a Console app from Graphic app and pick up the output
Look at MSDN article # Q126628
"How to Spawn a Console App and Refdirect Standard Handles".

Quote:

>Hello,

>I'm trying to execute a console program from a graphic (MFC)
>application (under Win 95, with VC5), without showing its console, and
>pick up its standard output (or error) in a CString
>variable. I think ShellExecute (or ShellExecuteEx)
>doesn't allow to get program's stdout. So I tryed to
>do it with CreateProcess redirecting standard handles.

>If someone has a similar experiance or knows how to do
>the thing properly, please help. I would really apreciate
>any help.

>Here is my code which doesn't work all the time. I'm not
>sure about some parameters (I marked this lines of the
>code with ****).

>BOOL MyExecCommandWithOutput(CString& strList, LPTSTR lpCommandLine ,
>LPVOID lpEnv)
>/*
>   strList: receives the stdout or stderr
>   lpCommandLine: pointer to the command line
>   lpEnv: pointer to the new environment
>*/
>{

> DWORD dwExitCode;
> HANDLE hChildStdoutRd , hChildStdoutWr;
> HANDLE hChildStderrRd , hChildStderrWr;

> SECURITY_ATTRIBUTES saAttr;
> PROCESS_INFORMATION piProcInfo;
> STARTUPINFO siStartInfo;

> // Set up members of SECURITY_ATTRIBUTES structure.
> ZeroMemory( &saAttr, sizeof(SECURITY_ATTRIBUTES) );
> saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);

> // **** I'm not sure about this
> saAttr.bInheritHandle = TRUE;

> if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, PIPEBUF))
> MyErrorExit("Stdout pipe creation failed\n");

> if (! CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, PIPEBUF))
> MyErrorExit("Stdout pipe creation failed\n");

> // Set up members of STARTUPINFO structure.
> ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
> siStartInfo.cb = sizeof(STARTUPINFO);
> siStartInfo.lpReserved = NULL;
> siStartInfo.lpReserved2 = NULL;
> siStartInfo.cbReserved2 = 0;
> siStartInfo.lpDesktop = NULL;

> // Use created pipes as stdout and stderr
> siStartInfo.dwFlags = STARTF_USESTDHANDLES;
> siStartInfo.hStdOutput = hChildStdoutWr;
> siStartInfo.hStdError = hChildStderrWr;

> // Don't show program's console
> // **** I'm not sure about this
> DWORD dwFlag =  DETACHED_PROCESS;

> // Create the child process.
> BOOL bl;
> bl = CreateProcess(NULL,
> lpCommandLine, // command line
> NULL,          // process security attributes
> NULL,          // primary thread security attributes
> TRUE,          // handles are inherited **** I'm not sure about this
> dwFlag,        // creation flags
> lpEnv,         // environment
> NULL,          // use parent's current directory
>   &siStartInfo,  // STARTUPINFO pointer
> &piProcInfo);  // receives PROCESS_INFORMATION

> if (!bl)
>        MyErrorExit("Create process failed");

> if (!GetExitCodeProcess(piProcInfo.hProcess, &dwExitCode))
> MyErrorExit("GetExitCodeProcess failed.\n");

> // Close the write end of the pipe before reading from the
>    // read end of the pipe.
>    if (! CloseHandle(hChildStdoutWr) ||
> ! CloseHandle(hChildStderrWr) )
>        MyErrorExit("Closing handle failed");

> // Get the results
> if (dwExitCode != 1) {
> // Program exited with code 0.
> // Read the stdout.
> MyReadFile2Str(strList , hChildStdoutRd);
> if (! CloseHandle(hChildStdoutRd) ||
> ! CloseHandle(hChildStderrRd) )
> MyErrorExit("Closing handle failed");
> return TRUE;
> }
> else {
> // Program exited with nonzero code.
> // Read the stderr.
> MyReadFile2Str(strList , hChildStderrRd);
> if (! CloseHandle(hChildStdoutRd) ||
> ! CloseHandle(hChildStderrRd) )
> MyErrorExit("Closing handle failed");
> return FALSE;
> }
>}

>VOID MyReadFile2Str(CString& str , HANDLE hRead)
>/*
>   str: receives the results
>   hRead: handle to the file to read from
>*/
>{
> str.Empty();
>    DWORD dwRead;
> CHAR chBuf[BUFSIZE+1];

>    // Read output from hRead handle, and write it in the chBuf array.
> BOOL br;
>    for (;;) {
> br =

 ReadFile(hRead, chBuf, BUFSIZE, &dwRead, NULL);

- Show quoted text -

Quote:
> if (!br || dwRead == 0)
> break;

> strlist += CString(chBuf, dwRead);
> }
> return;
>}

>___________________________________________________________
>Vartan Akopian
>University of Southern California
>Department of Mathematics
>1042 W. 36th Place, DRB 155
>Los Angeles, CA 90089-1113




Wed, 04 Jul 2001 03:00:00 GMT  
 How to run a Console app from Graphic app and pick up the output
Try the following code. It worked for me at least. Hope it will
help you also.

........................................................................
SECURITY_ATTRIBUTES lsa;
STARTUPINFO         si;
PROCESS_INFORMATION pi;
LPPROCESS_INFORMATION lppi=π

HANDLE hReadPipe, hWritePipe;

CWaitCursor WaitCursor;
lsa.nLength=sizeof(SECURITY_ATTRIBUTES);
lsa.lpSecurityDescriptor=NULL;
lsa.bInheritHandle=TRUE;

if (!CreatePipe(&hReadPipe,&hWritePipe,&lsa,0)) // create the pipe for
output
{
    AfxMessageBox("Couldnt create Pipe\n");
    return;

Quote:
}

memset(&si,0,sizeof(STARTUPINFO));
si.cb=sizeof(STARTUPINFO);

//important part - making SW_HIDE we prevent console to open up

si.dwFlags=STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
si.hStdOutput=hWritePipe;

if (!CreateProcess(NULL,
                  "test.exe",
                  NULL,
                  NULL,
                  TRUE,
                  0,
                  NULL,
                  NULL,
                  &si,
                  &pi))
{
     AfxMessageBox("Couldnt Create Process\r\n");
     return;

Quote:
}

DWORD cchReadBuffer;  // number of bytes read or to be written
CString sText;
TCHAR ph[5000];

//lets read our output, while being able to catch the moment of program
//shutdown

for (;;){
    cchReadBuffer = 0;
     if(!PeekNamedPipe(hReadPipe,            // ReadFile is blocking call so we should first
         ph,1,&cchReadBuffer,NULL,NULL))   // check if we have something to read
         break;
     if(cchReadBuffer){                 // yes we do, so read it and print out to the edit ctrl
         if (!ReadFile(hReadPipe,
               ph,
               4096,
              &cchReadBuffer,  // number of bytes actually read
               NULL))
                break;
          ph[cchReadBuffer] = 0;

         YourEdit.GetWindowText(sText);
        sText += ph;
        YourEdit.SetWindowText(sText);
        YourEdit.UpdateWindow();

   }
    else     // no we don't have anything in the buffer
          //maybe the program exited
          if(WaitForSingleObject(pi.hProcess,0) == WAIT_OBJECT_0)
               break;        // so we should exit either
          Sleep(500);
        // continue otherwise
     }

Quote:
}

CloseHandle(hReadPipe);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(hWritePipe);

--
Dima Shamroni
Abirnet Ltd., MEMCO Software Company

---
AbirNet, Ltd., A MEMCO Software Company
AbirNet provides the next generation in network protection and Internet
and Intranet intrusion and abuse protection.  AbirNet provides Windows 95
and NT-based software that provides no-overhead see-it-all filtering,
blocking, alerting, logging, and scanning.
Take a test drive of SessionWall-3 today - go to www.AbirNet.com or ask
about SessionWall-3 at (817) 251-7000 or (800)245-1688.
---

Quote:

>Hello,

>I'm trying to execute a console program from a graphic (MFC)
>application (under Win 95, with VC5), without showing its console, and
>pick up its standard output (or error) in a CString
>variable. I think ShellExecute (or ShellExecuteEx)
>doesn't allow to get program's stdout. So I tryed to
>do it with CreateProcess redirecting standard handles.

>If someone has a similar experiance or knows how to do
>the thing properly, please help. I would really apreciate
>any help.

>Here is my code which doesn't work all the time. I'm not
>sure about some parameters (I marked this lines of the
>code with ****).

>BOOL MyExecCommandWithOutput(CString& strList, LPTSTR lpCommandLine ,
>LPVOID lpEnv)
>/*
>   strList: receives the stdout or stderr
>   lpCommandLine: pointer to the command line
>   lpEnv: pointer to the new environment
>*/
>{

> DWORD dwExitCode;
> HANDLE hChildStdoutRd , hChildStdoutWr;
> HANDLE hChildStderrRd , hChildStderrWr;

> SECURITY_ATTRIBUTES saAttr;
> PROCESS_INFORMATION piProcInfo;
> STARTUPINFO siStartInfo;

> // Set up members of SECURITY_ATTRIBUTES structure.
> ZeroMemory( &saAttr, sizeof(SECURITY_ATTRIBUTES) );
> saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);

> // **** I'm not sure about this
> saAttr.bInheritHandle = TRUE;

> if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, PIPEBUF))
> MyErrorExit("Stdout pipe creation failed\n");

> if (! CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, PIPEBUF))
> MyErrorExit("Stdout pipe creation failed\n");

> // Set up members of STARTUPINFO structure.
> ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
> siStartInfo.cb = sizeof(STARTUPINFO);
> siStartInfo.lpReserved = NULL;
> siStartInfo.lpReserved2 = NULL;
> siStartInfo.cbReserved2 = 0;
> siStartInfo.lpDesktop = NULL;

> // Use created pipes as stdout and stderr
> siStartInfo.dwFlags = STARTF_USESTDHANDLES;
> siStartInfo.hStdOutput = hChildStdoutWr;
> siStartInfo.hStdError = hChildStderrWr;

> // Don't show program's console
> // **** I'm not sure about this
> DWORD dwFlag =  DETACHED_PROCESS;

> // Create the child process.
> BOOL bl;
> bl = CreateProcess(NULL,
> lpCommandLine, // command line
> NULL,          // process security attributes
> NULL,          // primary thread security attributes
> TRUE,          // handles are inherited **** I'm not sure about this
> dwFlag,        // creation flags
> lpEnv,         // environment
> NULL,          // use parent's current directory
>   &siStartInfo,  // STARTUPINFO pointer
> &piProcInfo);  // receives PROCESS_INFORMATION

> if (!bl)
>        MyErrorExit("Create process failed");

> if (!GetExitCodeProcess(piProcInfo.hProcess, &dwExitCode))
> MyErrorExit("GetExitCodeProcess failed.\n");

> // Close the write end of the pipe before reading from the
>    // read end of the pipe.
>    if (! CloseHandle(hChildStdoutWr) ||
> ! CloseHandle(hChildStderrWr) )
>        MyErrorExit("Closing handle failed");

> // Get the results
> if (dwExitCode != 1) {
> // Program exited with code 0.
> // Read the stdout.
> MyReadFile2Str(strList , hChildStdoutRd);
> if (! CloseHandle(hChildStdoutRd) ||
> ! CloseHandle(hChildStderrRd) )
> MyErrorExit("Closing handle failed");
> return TRUE;
> }
> else {
> // Program exited with nonzero code.
> // Read the stderr.
> MyReadFile2Str(strList , hChildStderrRd);
> if (! CloseHandle(hChildStdoutRd) ||
> ! CloseHandle(hChildStderrRd) )
> MyErrorExit("Closing handle failed");
> return FALSE;
> }
>}

>VOID MyReadFile2Str(CString& str , HANDLE hRead)
>/*
>   str: receives the results
>   hRead: handle to the file to read from
>*/
>{
> str.Empty();
>    DWORD dwRead;
> CHAR chBuf[BUFSIZE+1];

>    // Read output from hRead handle, and write it in the chBuf array.
> BOOL br;
>    for (;;) {
> br = ReadFile(hRead, chBuf, BUFSIZE, &dwRead, NULL);
> if (!br || dwRead == 0)
> break;

> strlist += CString(chBuf, dwRead);
> }
> return;
>}

>___________________________________________________________
>Vartan Akopian
>University of Southern California
>Department of Mathematics
>1042 W. 36th Place, DRB 155
>Los Angeles, CA 90089-1113




Thu, 05 Jul 2001 03:00:00 GMT  
 How to run a Console app from Graphic app and pick up the output

Quote:

> Try the following code. It worked for me at least. Hope it will
> help you also.

[Snip]

I've been trying to do this for some time now, but your example is the
only one that has ever worked the way I want.

Thanks,

--Matt



Sat, 07 Jul 2001 03:00:00 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. How to run a Console app from Graphic app and pick up the output

2. graphics output in Win32 console apps

3. Running a console app and scavenging its output

4. MFC and DOS apps - Redirecting console output to an MFC app (Newbie)

5. MFC and DOS apps - Redirecting console output to an MFC app (Newbie)

6. Run console app from within my gui app

7. Running a console app from a windows app

8. running other dos apps from a console app

9. Running console app from within a win32 app

10. Running console app from within a win32 app

11. running win32 apps and dos apps from a menu app

12. Output to console from a Windorms app

 

 
Powered by phpBB® Forum Software