Re: MFC: concurrent display of console output on GUI edit box.
//-------------------------------------------------------------------------=
----
// Calling process...
//-------------------------------------------------------------------------=
----
#include "process.h"
typedef void (__cdecl * TSend_Output)(const char * );
// remember to implement this function... ;-) for display output
extern TSend_Output Send_StdOutput ;
extern TSend_Output Send_StdError ;
void Read_OutPut( HANDLE h, TSend_Output Send_Output )
{
char Buf[512];
unsigned long avail=0; //bytes available
do
{
PeekNamedPipe(h, Buf, sizeof(Buf)-1,NULL, &avail,NULL);
//check to see if there is any data to read from stdout
if( avail ) // ce ne =E8 !!!!
{
unsigned long letti=0; //bytes available
if( ReadFile( h, Buf, min(avail,sizeof(Buf)-1), &letti,
NULL) )
{
Buf[letti] =0;
TRACE0(Buf);
if(Send_Output) Send_Output(Buf);
}
}
} while(avail);
}
bool CallProcess( const CString & cmd )
{
try
{
char buf[1024];
strcpy( buf, cmd);
PROCESS_INFORMATION pInfo;
STARTUPINFO sInfo;
memset(&sInfo,0,sizeof(STARTUPINFO));
memset(&pInfo,0,sizeof(PROCESS_INFORMATION));
sInfo.cb = sizeof(STARTUPINFO);
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = FALSE;
sa.lpSecurityDescriptor = NULL;
HANDLE hIRead=NULL, hIWrite=NULL;
HANDLE hORead=NULL, hOWrite=NULL;
HANDLE hERead=NULL, hEWrite=NULL;
BOOL retpipeI =retpipeI = CreatePipe(&hIRead, &hIWrite, &sa,
NULL);
BOOL retpipeO =retpipeO = CreatePipe(&hORead, &hOWrite, &sa,
NULL);
BOOL retpipeE =retpipeE = CreatePipe(&hERead, &hEWrite, &sa,
NULL);
BOOL cp=FALSE;
if( retpipeI && retpipeO && retpipeE )
{
HANDLE hProcess = GetCurrentProcess();
DuplicateHandle(hProcess, hIRead , hProcess,
&sInfo.hStdInput , 0, TRUE, DUPLICATE_SAME_ACCESS |
DUPLICATE_CLOSE_SOURCE);
DuplicateHandle(hProcess, hOWrite, hProcess,
&sInfo.hStdOutput, 0, TRUE, DUPLICATE_SAME_ACCESS |
DUPLICATE_CLOSE_SOURCE);
DuplicateHandle(hProcess, hEWrite, hProcess,
&sInfo.hStdError , 0, TRUE, DUPLICATE_SAME_ACCESS |
DUPLICATE_CLOSE_SOURCE);
sInfo.dwFlags = STARTF_USESTDHANDLES|
STARTF_USESHOWWINDOW;
sInfo.wShowWindow = SW_HIDE;
cp = CreateProcess(NULL,
buf,
NULL,
NULL,
TRUE,
0,
NULL,
NULL,
&sInfo,
&pInfo);
}
else
{
sInfo.dwFlags = 0;
cp = CreateProcess(NULL,
buf,
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&sInfo,
&pInfo);
}
if( ! cp )
return false;
Sleep( 200 );
FILETIME CreationTime; // when the process was created
FILETIME ExitTime; // when the process exited
FILETIME KernelTime; // time the process has spent in kernel
mode
ULARGE_INTEGER UserTime; // time the process has spent in
user mode
ULARGE_INTEGER LastUserTime; // time the process has spent
in user mode
LastUserTime.QuadPart=0;
unsigned TimeDead = 0; //
const unsigned TimeOut = 60000; // un minuto
const unsigned gap = 10;
// Give the process time to execute and finish
DWORD ret;
do
{
ret = WaitForSingleObject(pInfo.hProcess, gap);
if( GetProcessTimes( pInfo.hProcess, &CreationTime,
&ExitTime, &KernelTime, (FILETIME *)&UserTime ) )
{
ULARGE_INTEGER dif;
dif.QuadPart = UserTime.QuadPart -
LastUserTime.QuadPart;
unsigned div=1000;
if( unsigned(dif.QuadPart/div) )
{
LastUserTime.QuadPart = UserTime.QuadPart;
TimeDead = 0; // ci ripenso, ma non troppo...
}
else
{
TimeDead += gap;
}
}
if( ret == WAIT_TIMEOUT && retpipeI && retpipeO &&
retpipeE )
{
Read_OutPut(hORead, Send_StdOutput );
Read_OutPut(hERead, Send_StdError );
}
}
while( ret == WAIT_TIMEOUT );
TRACE1("\n GetLastError=%d", GetLastError() );
if( retpipeI && retpipeO && retpipeE )
{
Read_OutPut(hORead, Send_StdOutput );
Read_OutPut(hERead, Send_StdError );
CloseHandle(hIWrite);
CloseHandle(hORead);
CloseHandle(hERead);
CloseHandle(sInfo.hStdInput );
CloseHandle(sInfo.hStdOutput);
CloseHandle(sInfo.hStdError );
}
DWORD exitCode;
if (GetExitCodeProcess(pInfo.hProcess, &exitCode))
{
switch(exitCode)
{
case STILL_ACTIVE:
assert(0); // come e' potuto succedere???
break;
default:
break;
}
}
CloseHandle(pInfo.hProcess);
CloseHandle(pInfo.hThread);
}
catch(...)
{
return false;
}
return true;
}