susiriss
September 26th, 2006, 06:19 AM
Hi all,
I am developing a program to communicate with a console mode application. So I spawned a child console process, created two pipes for Stdinput and Stdoutput of the console process, redirected their handles so that my process can communicate with it. First I tried to run cmd.exe on the console window, and test some commands in it. The command prompt appears on the console but my command does not display or executed. However, when I debug the app, I see the WriteFile succedes and the desired no. of bytes are written to the pipe. My code look like the following. Could you please help me & identify what I'm missing ....!
void CConsole::Create()
{
HANDLE hStdinWriteTmp,hStdoutReadTmp;// Temporary handles used by the parent
HANDLE hStdinRead,hStdoutWrite,hStdError;// Stdin, Stdout & Stderror handles
AllocConsole(); // Allocate my one and only console
SECURITY_ATTRIBUTES sa;
sa.bInheritHandle=TRUE;
sa.lpSecurityDescriptor=NULL;
sa.nLength=sizeof(SECURITY_ATTRIBUTES);
// Creating pipe for child's input
CreatePipe(&hStdinRead,&hStdinWriteTmp,&sa,0);
// Creating pipe for child's output
if(!CreatePipe(&hStdoutReadTmp,&hStdoutWrite,&sa,0))
AfxMessageBox("pipe failed",MB_ICONERROR,0);
//Duplicate the Write handle so that it is not inheritable
::DuplicateHandle(::GetCurrentProcess(),hStdinWriteTmp,
::GetCurrentProcess(),&m_hStdinWrite, 0,
FALSE,DUPLICATE_SAME_ACCESS);
//Duplicate the Read handle so that it is not inheritable
::DuplicateHandle(::GetCurrentProcess(),hStdoutReadTmp,
::GetCurrentProcess(),&m_hStdoutRead, 0,
FALSE,DUPLICATE_SAME_ACCESS);
//Duplicate handle for the Std Error
::DuplicateHandle(::GetCurrentProcess(),hStdoutWrite,
::GetCurrentProcess(),&hStdError, 0,
TRUE,DUPLICATE_SAME_ACCESS);
//Close the duplicate handles inherited by the child
CloseHandle(hStdinWriteTmp);
CloseHandle(hStdoutReadTmp);
hStdinWriteTmp=INVALID_HANDLE_VALUE;
hStdoutReadTmp=INVALID_HANDLE_VALUE;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
si.hStdOutput = hStdoutWrite;//GetStdHandle(STD_OUTPUT_HANDLE);//
si.hStdInput = hStdinRead;//GetStdHandle(STD_INPUT_HANDLE);
si.hStdError = hStdError;//GetStdHandle(STD_ERROR_HANDLE);
si.wShowWindow = SW_SHOW;
si.dwFlags = STARTF_USESTDHANDLES;//| STARTF_USESHOWWINDOW;// ;
ZeroMemory( &pi, sizeof(pi) );
if(!::CreateProcess(NULL,"cmd.exe ",
NULL,NULL,FALSE,CREATE_NEW_PROCESS_GROUP,//CREATE_NEW_PROCESS_GROUP|
NULL,
NULL,&si,&pi))
AfxMessageBox("Process Error",MB_ICONERROR,0);
Execute("notepad\r\n");
CloseHandle(hStdinRead);
CloseHandle(hStdoutWrite);
CloseHandle(hStdError);
}
BOOL CConsole::Execute(LPCSTR szCmd)
{
DWORD nBytesWritten;
CString sCmd(szCmd);
if(!::WriteFile(m_hStdinWrite,(LPCTSTR)sCmd,sCmd.GetLength(),&nBytesWritten,NULL))
{
AfxMessageBox("Write to pipe failed",MB_ICONERROR,0);
return FALSE;
}
else
{
return TRUE;
}
}
I am developing a program to communicate with a console mode application. So I spawned a child console process, created two pipes for Stdinput and Stdoutput of the console process, redirected their handles so that my process can communicate with it. First I tried to run cmd.exe on the console window, and test some commands in it. The command prompt appears on the console but my command does not display or executed. However, when I debug the app, I see the WriteFile succedes and the desired no. of bytes are written to the pipe. My code look like the following. Could you please help me & identify what I'm missing ....!
void CConsole::Create()
{
HANDLE hStdinWriteTmp,hStdoutReadTmp;// Temporary handles used by the parent
HANDLE hStdinRead,hStdoutWrite,hStdError;// Stdin, Stdout & Stderror handles
AllocConsole(); // Allocate my one and only console
SECURITY_ATTRIBUTES sa;
sa.bInheritHandle=TRUE;
sa.lpSecurityDescriptor=NULL;
sa.nLength=sizeof(SECURITY_ATTRIBUTES);
// Creating pipe for child's input
CreatePipe(&hStdinRead,&hStdinWriteTmp,&sa,0);
// Creating pipe for child's output
if(!CreatePipe(&hStdoutReadTmp,&hStdoutWrite,&sa,0))
AfxMessageBox("pipe failed",MB_ICONERROR,0);
//Duplicate the Write handle so that it is not inheritable
::DuplicateHandle(::GetCurrentProcess(),hStdinWriteTmp,
::GetCurrentProcess(),&m_hStdinWrite, 0,
FALSE,DUPLICATE_SAME_ACCESS);
//Duplicate the Read handle so that it is not inheritable
::DuplicateHandle(::GetCurrentProcess(),hStdoutReadTmp,
::GetCurrentProcess(),&m_hStdoutRead, 0,
FALSE,DUPLICATE_SAME_ACCESS);
//Duplicate handle for the Std Error
::DuplicateHandle(::GetCurrentProcess(),hStdoutWrite,
::GetCurrentProcess(),&hStdError, 0,
TRUE,DUPLICATE_SAME_ACCESS);
//Close the duplicate handles inherited by the child
CloseHandle(hStdinWriteTmp);
CloseHandle(hStdoutReadTmp);
hStdinWriteTmp=INVALID_HANDLE_VALUE;
hStdoutReadTmp=INVALID_HANDLE_VALUE;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
si.hStdOutput = hStdoutWrite;//GetStdHandle(STD_OUTPUT_HANDLE);//
si.hStdInput = hStdinRead;//GetStdHandle(STD_INPUT_HANDLE);
si.hStdError = hStdError;//GetStdHandle(STD_ERROR_HANDLE);
si.wShowWindow = SW_SHOW;
si.dwFlags = STARTF_USESTDHANDLES;//| STARTF_USESHOWWINDOW;// ;
ZeroMemory( &pi, sizeof(pi) );
if(!::CreateProcess(NULL,"cmd.exe ",
NULL,NULL,FALSE,CREATE_NEW_PROCESS_GROUP,//CREATE_NEW_PROCESS_GROUP|
NULL,
NULL,&si,&pi))
AfxMessageBox("Process Error",MB_ICONERROR,0);
Execute("notepad\r\n");
CloseHandle(hStdinRead);
CloseHandle(hStdoutWrite);
CloseHandle(hStdError);
}
BOOL CConsole::Execute(LPCSTR szCmd)
{
DWORD nBytesWritten;
CString sCmd(szCmd);
if(!::WriteFile(m_hStdinWrite,(LPCTSTR)sCmd,sCmd.GetLength(),&nBytesWritten,NULL))
{
AfxMessageBox("Write to pipe failed",MB_ICONERROR,0);
return FALSE;
}
else
{
return TRUE;
}
}