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